From e7696bbcb37c48fa72041012a529f149470b8374 Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Mon, 1 Sep 2025 14:22:25 -0700 Subject: [PATCH 01/24] chore(minecraft): implementation breakages of 25w32a Breaking Change: - Removed Spawn Chunk Radius gamerule - Removed jagged noise generation configuration See: https://minecraft.wiki/w/Java_Edition_25w32a --- SpongeAPI | 2 +- .../BlockStatePropertiesGenerator.java | 7 +++ .../BlockStatePropertyKeysGenerator.java | 6 +++ .../vanilla/generator/Context.java | 10 ++-- .../world/level/block/BlockRegistries.java | 24 +++++++++ gradle.properties | 2 +- gradle/verification-metadata.xml | 22 +++++++++ .../accessor/network/chat/StyleAccessor.java | 36 ++++++++++---- .../server/MinecraftServerAccessor.java | 6 +-- .../server/level/ServerLevelAccessor.java | 4 -- ...eProfileCache_GameProfileInfoAccessor.java | 8 +-- .../item/component/CustomDataAccessor.java | 3 ++ .../common/adventure/SpongeAdventure.java | 25 ++++++++-- .../common/ban/SpongeBanBuilder.java | 2 +- .../server/level/ServerLevelBridge.java | 3 -- .../SpongeGameProfileValueParameter.java | 3 +- .../provider/block/entity/BannerData.java | 5 +- .../block/state/BlockStateDataProvider.java | 2 + .../data/provider/entity/EntityData.java | 4 +- .../data/provider/entity/PaintingData.java | 2 +- .../data/provider/entity/VanishableData.java | 2 +- .../item/stack/SignItemStackData.java | 10 ++-- .../item/stack/SpawnEggItemStackData.java | 14 ++++-- .../common/effect/util/ViewerPacketUtil.java | 2 +- .../entity/living/human/HumanEntity.java | 43 +++++++--------- .../event/SpongeCommonEventFactory.java | 35 +++++-------- .../phase/tick/EntityTickPhaseState.java | 2 +- .../custom/CarriedWrapperInventory.java | 11 +---- .../custom/ViewableCustomInventory.java | 10 ---- .../common/item/SpongeItemStack.java | 37 +++++++++----- .../network/packet/SpongePacketHandler.java | 10 ++-- .../common/profile/SpongeGameProfile.java | 16 ++++++ .../profile/SpongeGameProfileManager.java | 2 +- .../service/server/ban/SpongeBanService.java | 23 ++++----- .../service/server/ban/SpongeUserBanList.java | 9 ++-- .../server/permission/UserCollection.java | 4 +- .../server/permission/UserSubject.java | 11 +++-- .../server/whitelist/SpongeUserWhiteList.java | 5 +- .../whitelist/SpongeWhitelistService.java | 11 +++-- .../common/user/SpongeUserManager.java | 3 +- .../world/server/SpongeTicketTypeBuilder.java | 7 ++- .../world/server/SpongeWorldManager.java | 49 ++++--------------- .../players/GameProfileCacheMixin_API.java | 18 +++---- .../CopperGolemStatueBlock_PoseMixin_API.java | 33 +++++++++++++ ...eatheringCopper_WeatherStateMixin_API.java | 33 +++++++++++++ .../block/entity/BlockEntityMixin_API.java | 2 +- .../entity/SpawnerBlockEntityMixin_API.java | 2 +- .../TrialSpawnerBlockEntityMixin_API.java | 2 +- .../level/levelgen/NoiseRouterMixin_API.java | 6 --- .../adventure/text/format/StyleImplMixin.java | 2 +- .../mixin/core/block/BedBlockMixin.java | 2 +- .../server/IntegratedPlayerListMixin.java | 11 +++-- .../syncher/SynchedEntityDataMixin.java | 2 +- .../core/server/MinecraftServerMixin.java | 27 ++++++---- .../dedicated/DedicatedPlayerListMixin.java | 9 ++-- .../dedicated/DedicatedServerMixin.java | 22 ++++----- .../core/server/level/ServerLevelMixin.java | 28 ++--------- .../server/players/GameProfileCacheMixin.java | 38 +++++++------- ...GameProfileCache_GameProfileInfoMixin.java | 11 +++-- .../mixin/core/world/entity/EntityMixin.java | 18 +++---- .../core/world/entity/LeashableMixin.java | 4 +- .../core/world/entity/LightningBoltMixin.java | 4 +- .../core/world/entity/LivingEntityMixin.java | 16 +++--- .../mixin/core/world/entity/MobMixin.java | 2 +- .../world/entity/item/ItemEntityMixin.java | 2 +- .../world/entity/item/PrimedTntMixin.java | 2 +- .../world/entity/monster/CreeperMixin.java | 4 +- .../entity/projectile/AbstractArrowMixin.java | 2 +- .../projectile/FireworkRocketEntityMixin.java | 2 +- .../entity/projectile/FishingHookMixin.java | 2 +- .../projectile/ProjectileUtilMixin.java | 2 +- .../core/world/item/FishingRodItemMixin.java | 2 +- .../mixin/core/world/item/ItemStackMixin.java | 6 +-- .../world/level/block/CampfireBlockMixin.java | 2 +- .../world/level/block/MagmaBlockMixin.java | 2 +- .../block/PointedDripstoneBlockMixin.java | 2 +- .../level/block/SweetBerryBushBlockMixin.java | 2 +- .../block/entity/BannerBlockEntityMixin.java | 2 +- .../level/storage/PlayerDataStorageMixin.java | 7 ++- .../core/world/ticks/SavedTickMixin.java | 3 +- .../AbstractContainerMenuMixin_Inventory.java | 2 +- .../entity/LivingEntityMixin_Tracker.java | 2 +- .../SerializableChunkDataMixin_Tracker.java | 2 + src/mixins/resources/mixins.sponge.api.json | 2 + .../client/gui/widget/MetadataPanel.java | 4 +- .../client/gui/widget/ScrollPanel.java | 4 +- .../gui/widget/list/FilterableList.java | 16 +++--- .../gui/widget/list/PluginSelectionList.java | 2 +- .../server/packs/PluginPackResources.java | 10 +++- .../server/MinecraftServerMixin_Vanilla.java | 4 +- .../level/block/FireBlockMixin_Vanilla.java | 4 +- 91 files changed, 508 insertions(+), 372 deletions(-) create mode 100644 src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/CopperGolemStatueBlock_PoseMixin_API.java create mode 100644 src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/WeatheringCopper_WeatherStateMixin_API.java diff --git a/SpongeAPI b/SpongeAPI index 6f5f4d6747d..6252dce257b 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit 6f5f4d6747d397db0dc906349e39beea132fda91 +Subproject commit 6252dce257b18be1897b5c07d946ff2886fbf79b diff --git a/generator/src/main/java/org/spongepowered/vanilla/generator/BlockStatePropertiesGenerator.java b/generator/src/main/java/org/spongepowered/vanilla/generator/BlockStatePropertiesGenerator.java index 42c43f0c7db..fbd3387f2e3 100644 --- a/generator/src/main/java/org/spongepowered/vanilla/generator/BlockStatePropertiesGenerator.java +++ b/generator/src/main/java/org/spongepowered/vanilla/generator/BlockStatePropertiesGenerator.java @@ -32,6 +32,8 @@ import net.minecraft.core.FrontAndTop; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.CopperGolemStatueBlock; +import net.minecraft.world.level.block.WeatheringCopper; import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerState; import net.minecraft.world.level.block.entity.vault.VaultState; import net.minecraft.world.level.block.state.BlockState; @@ -56,6 +58,7 @@ import net.minecraft.world.level.block.state.properties.RailShape; import net.minecraft.world.level.block.state.properties.RedstoneSide; import net.minecraft.world.level.block.state.properties.SculkSensorPhase; +import net.minecraft.world.level.block.state.properties.SideChainPart; import net.minecraft.world.level.block.state.properties.SlabType; import net.minecraft.world.level.block.state.properties.StairsShape; import net.minecraft.world.level.block.state.properties.StructureMode; @@ -152,6 +155,10 @@ static PropertyType ofProperty(final Property prop) { vanillaEnumTypeMapping.put(VaultState.class, BlockStatePropertiesGenerator.inDataTypePkg("VaultState")); vanillaEnumTypeMapping.put(CreakingHeartState.class, BlockStatePropertiesGenerator.inDataTypePkg("CreakingHeartState")); vanillaEnumTypeMapping.put(TestBlockMode.class, BlockStatePropertiesGenerator.inDataTypePkg("TestBlockMode")); + vanillaEnumTypeMapping.put(SideChainPart.class, BlockStatePropertiesGenerator.inDataTypePkg("SideChainPart")); + vanillaEnumTypeMapping.put(CopperGolemStatueBlock.Pose.class, BlockStatePropertiesGenerator.inDataTypePkg("CopperGolemPose")); + vanillaEnumTypeMapping.put(WeatheringCopper.WeatherState.class, BlockStatePropertiesGenerator.inDataTypePkg("CopperOxidation")); + // Custom Mapping required see StateHolderMixin_API final ClassName portionTypeClass = BlockStatePropertiesGenerator.inDataTypePkg("PortionType"); diff --git a/generator/src/main/java/org/spongepowered/vanilla/generator/BlockStatePropertyKeysGenerator.java b/generator/src/main/java/org/spongepowered/vanilla/generator/BlockStatePropertyKeysGenerator.java index 2950b25a61b..c012945d60a 100644 --- a/generator/src/main/java/org/spongepowered/vanilla/generator/BlockStatePropertyKeysGenerator.java +++ b/generator/src/main/java/org/spongepowered/vanilla/generator/BlockStatePropertyKeysGenerator.java @@ -33,6 +33,8 @@ import com.squareup.javapoet.TypeVariableName; import net.minecraft.core.Direction; import net.minecraft.core.FrontAndTop; +import net.minecraft.world.level.block.CopperGolemStatueBlock; +import net.minecraft.world.level.block.WeatheringCopper; import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerState; import net.minecraft.world.level.block.entity.vault.VaultState; import net.minecraft.world.level.block.state.BlockState; @@ -57,6 +59,7 @@ import net.minecraft.world.level.block.state.properties.RailShape; import net.minecraft.world.level.block.state.properties.RedstoneSide; import net.minecraft.world.level.block.state.properties.SculkSensorPhase; +import net.minecraft.world.level.block.state.properties.SideChainPart; import net.minecraft.world.level.block.state.properties.SlabType; import net.minecraft.world.level.block.state.properties.StairsShape; import net.minecraft.world.level.block.state.properties.StructureMode; @@ -150,6 +153,9 @@ static BlockStatePropertyKeysGenerator.PropertyType ofProperty(final Property vanillaEnumTypeMapping.put(VaultState.class, BlockStatePropertyKeysGenerator.inDataTypePkg("VaultState")); vanillaEnumTypeMapping.put(CreakingHeartState.class, BlockStatePropertyKeysGenerator.inDataTypePkg("CreakingHeartState")); vanillaEnumTypeMapping.put(TestBlockMode.class, BlockStatePropertyKeysGenerator.inDataTypePkg("TestBlockMode")); + vanillaEnumTypeMapping.put(SideChainPart.class, BlockStatePropertyKeysGenerator.inDataTypePkg("SideChain")); + vanillaEnumTypeMapping.put(CopperGolemStatueBlock.Pose.class, BlockStatePropertyKeysGenerator.inDataTypePkg("CopperGolemPose")); + vanillaEnumTypeMapping.put(WeatheringCopper.WeatherState.class, BlockStatePropertyKeysGenerator.inDataTypePkg("CopperOxidation")); // Custom Mapping required see StateHolderMixin_API final ClassName portionTypeClass = BlockStatePropertyKeysGenerator.inDataTypePkg("PortionType"); diff --git a/generator/src/main/java/org/spongepowered/vanilla/generator/Context.java b/generator/src/main/java/org/spongepowered/vanilla/generator/Context.java index e47330f862f..2fcecf82f13 100644 --- a/generator/src/main/java/org/spongepowered/vanilla/generator/Context.java +++ b/generator/src/main/java/org/spongepowered/vanilla/generator/Context.java @@ -85,9 +85,13 @@ public ClassName relativeClass(final String relativePackage, final String simple public CompilationUnit compilationUnit(final String relativePackage, final String simpleName) { final String pkg = relativePackage.isBlank() ? Context.BASE_PACKAGE : String.join(".", Context.BASE_PACKAGE, relativePackage); - final CompilationUnit unit = this.sourceRoot.parse(pkg, simpleName + ".java"); - LexicalPreservingPrinter.setup(unit); - return unit; + try { + final CompilationUnit unit = this.sourceRoot.parse(pkg, simpleName + ".java"); + LexicalPreservingPrinter.setup(unit); + return unit; + } catch (Exception e) { + throw new RuntimeException("Failed to parse " + simpleName + ".java", e); + } } /** diff --git a/generator/src/main/java/org/spongepowered/vanilla/generator/world/level/block/BlockRegistries.java b/generator/src/main/java/org/spongepowered/vanilla/generator/world/level/block/BlockRegistries.java index adae5b92228..59d1f58a69c 100644 --- a/generator/src/main/java/org/spongepowered/vanilla/generator/world/level/block/BlockRegistries.java +++ b/generator/src/main/java/org/spongepowered/vanilla/generator/world/level/block/BlockRegistries.java @@ -26,12 +26,15 @@ import net.minecraft.core.registries.Registries; import net.minecraft.world.level.Explosion; +import net.minecraft.world.level.block.CopperGolemStatueBlock; +import net.minecraft.world.level.block.WeatheringCopper; import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerState; import net.minecraft.world.level.block.state.properties.BambooLeaves; import net.minecraft.world.level.block.state.properties.CreakingHeartState; import net.minecraft.world.level.block.state.properties.DripstoneThickness; import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; import net.minecraft.world.level.block.state.properties.SculkSensorPhase; +import net.minecraft.world.level.block.state.properties.SideChainPart; import net.minecraft.world.level.block.state.properties.TestBlockMode; import net.minecraft.world.level.block.state.properties.Tilt; import org.spongepowered.vanilla.generator.BlockStateDataProviderGenerator; @@ -90,6 +93,27 @@ public static List enumRegistries(final Context context) { TrialSpawnerState.class, "getSerializedName", "sponge" + ), + new EnumEntriesValidator<>( + "data.type", + "CopperGolemPoses", + CopperGolemStatueBlock.Pose.class, + "getSerializedName", + "sponge" + ), + new EnumEntriesValidator<>( + "data.type", + "SideChains", + SideChainPart.class, + "getSerializedName", + "sponge" + ), + new EnumEntriesValidator<>( + "data.type", + "CopperOxidization", + WeatheringCopper.WeatherState.class, + "getSerializedName", + "sponge" ) ); } diff --git a/gradle.properties b/gradle.properties index 122e233ee07..335000978ef 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.c mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json superClassChanges=common.superclasschange -minecraftVersion=1.21.8 +minecraftVersion=25w32a recommendedVersion=0-SNAPSHOT org.gradle.dependency.verification.console=verbose diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 1c5583bc573..48cb727cd6e 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -1491,6 +1491,14 @@ + + + + + + + + @@ -1568,6 +1576,20 @@ + + + + + + + + + + + + + + diff --git a/src/accessors/java/org/spongepowered/common/accessor/network/chat/StyleAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/network/chat/StyleAccessor.java index d7d933d9354..cead56cb855 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/network/chat/StyleAccessor.java +++ b/src/accessors/java/org/spongepowered/common/accessor/network/chat/StyleAccessor.java @@ -25,6 +25,7 @@ package org.spongepowered.common.accessor.network.chat; import net.minecraft.network.chat.ClickEvent; +import net.minecraft.network.chat.FontDescription; import net.minecraft.network.chat.HoverEvent; import net.minecraft.network.chat.Style; import net.minecraft.network.chat.TextColor; @@ -40,23 +41,38 @@ public interface StyleAccessor { @Invoker("") - static Style invoker$new(final @Nullable TextColor color, final @Nullable Integer shadowColor, final @Nullable Boolean bold, final @Nullable Boolean italic, - final @Nullable Boolean underlined, final @Nullable Boolean strikethrough, final @Nullable Boolean obfuscated, - final @Nullable ClickEvent clickEvent, final @Nullable HoverEvent hoverEvent, final @Nullable String insertion, - final @Nullable ResourceLocation font) { + static Style invoker$new( + final @Nullable TextColor color, + final @Nullable Integer shadowColor, + final @Nullable Boolean bold, + final @Nullable Boolean italic, + final @Nullable Boolean underlined, + final @Nullable Boolean strikethrough, + final @Nullable Boolean obfuscated, + final @Nullable ClickEvent clickEvent, + final @Nullable HoverEvent hoverEvent, + final @Nullable String insertion, + final @Nullable FontDescription fontDescription + ) { throw new UntransformedInvokerError(); } - @Accessor("bold") Boolean accessor$bold(); + @Accessor("bold") + Boolean accessor$bold(); - @Accessor("italic") Boolean accessor$italic(); + @Accessor("italic") + Boolean accessor$italic(); - @Accessor("underlined") Boolean accessor$underlined(); + @Accessor("underlined") + Boolean accessor$underlined(); - @Accessor("strikethrough") Boolean accessor$strikethrough(); + @Accessor("strikethrough") + Boolean accessor$strikethrough(); - @Accessor("obfuscated") Boolean accessor$obfuscated(); + @Accessor("obfuscated") + Boolean accessor$obfuscated(); - @Accessor("font") ResourceLocation accessor$font(); + @Accessor("font") + FontDescription accessor$font(); } diff --git a/src/accessors/java/org/spongepowered/common/accessor/server/MinecraftServerAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/server/MinecraftServerAccessor.java index ac4332bf6b3..a6d7e9e6127 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/server/MinecraftServerAccessor.java +++ b/src/accessors/java/org/spongepowered/common/accessor/server/MinecraftServerAccessor.java @@ -27,7 +27,7 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.progress.ChunkProgressListenerFactory; +import net.minecraft.server.level.progress.LevelLoadListener; import net.minecraft.world.level.Level; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.ServerLevelData; @@ -49,7 +49,7 @@ public interface MinecraftServerAccessor { throw new UntransformedAccessorError(); } - @Invoker("setInitialSpawn") static void invoker$setInitialSpawn(final ServerLevel serverWorld, final ServerLevelData levelData, final boolean generateBonusChest, final boolean debugWorld) { + @Invoker("setInitialSpawn") static void invoker$setInitialSpawn(final ServerLevel serverWorld, final ServerLevelData levelData, final boolean generateBonusChest, final boolean debugWorld, LevelLoadListener listener) { throw new UntransformedInvokerError(); } @@ -59,8 +59,6 @@ public interface MinecraftServerAccessor { @Accessor("executor") Executor accessor$executor(); - @Accessor("progressListenerFactory") ChunkProgressListenerFactory accessor$progressListenerFactory(); - @Accessor("nextTickTimeNanos") void accessor$nextTickTimeNanos(final long nextTickTime); @Invoker("isSpawningMonsters") boolean invoker$isSpawningMonsters(); diff --git a/src/accessors/java/org/spongepowered/common/accessor/server/level/ServerLevelAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/server/level/ServerLevelAccessor.java index 52b13a0586e..aaa7ac898ae 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/server/level/ServerLevelAccessor.java +++ b/src/accessors/java/org/spongepowered/common/accessor/server/level/ServerLevelAccessor.java @@ -46,8 +46,4 @@ public interface ServerLevelAccessor { @Accessor("entityManager") PersistentEntitySectionManager accessor$getEntityManager(); - @Accessor("lastSpawnChunkRadius") int accessor$lastSpawnChunkRadius(); - - @Accessor("lastSpawnChunkRadius") void accessor$setLastSpawnChunkRadius(int value); - } diff --git a/src/accessors/java/org/spongepowered/common/accessor/server/players/GameProfileCache_GameProfileInfoAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/server/players/GameProfileCache_GameProfileInfoAccessor.java index e197f0ca804..7dac013db5f 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/server/players/GameProfileCache_GameProfileInfoAccessor.java +++ b/src/accessors/java/org/spongepowered/common/accessor/server/players/GameProfileCache_GameProfileInfoAccessor.java @@ -24,18 +24,18 @@ */ package org.spongepowered.common.accessor.server.players; -import com.mojang.authlib.GameProfile; +import net.minecraft.server.players.NameAndId; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; import java.util.Date; -@Mixin(targets = "net.minecraft.server.players.GameProfileCache$GameProfileInfo") +@Mixin(targets = "net.minecraft.server.players.CachedUserNameToIdResolver$GameProfileInfo") public interface GameProfileCache_GameProfileInfoAccessor { - @Invoker("getProfile") GameProfile invoker$getProfile(); + @Invoker("nameAndId") NameAndId invoker$nameAndId(); - @Invoker("getExpirationDate") Date invoker$getExpirationDate(); + @Invoker("expirationDate") Date invoker$getExpirationDate(); @Invoker("setLastAccess") void invoker$setLastAccess(final long lastAccessMs); diff --git a/src/accessors/java/org/spongepowered/common/accessor/world/item/component/CustomDataAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/world/item/component/CustomDataAccessor.java index 56e1b1af747..cdac3d9bcb2 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/world/item/component/CustomDataAccessor.java +++ b/src/accessors/java/org/spongepowered/common/accessor/world/item/component/CustomDataAccessor.java @@ -27,12 +27,15 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.component.CustomData; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Invoker; import org.spongepowered.common.UntransformedInvokerError; @Mixin(CustomData.class) public interface CustomDataAccessor { + @Accessor("tag") CompoundTag accessor$tag(); + @Invoker("") static CustomData invoker$new(CompoundTag tag) { throw new UntransformedInvokerError(); } diff --git a/src/main/java/org/spongepowered/common/adventure/SpongeAdventure.java b/src/main/java/org/spongepowered/common/adventure/SpongeAdventure.java index b09679ab007..2478f2342f3 100644 --- a/src/main/java/org/spongepowered/common/adventure/SpongeAdventure.java +++ b/src/main/java/org/spongepowered/common/adventure/SpongeAdventure.java @@ -72,6 +72,7 @@ import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.ComponentContents; +import net.minecraft.network.chat.FontDescription; import net.minecraft.network.chat.HoverEvent.Action; import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.contents.BlockDataSource; @@ -226,6 +227,15 @@ public static Key asAdventure(final ResourceLocation key) { return (Key) (Object) key; } + public static Key asAdventure(final FontDescription description) { + return switch (description) { + case null -> null; + case FontDescription.Resource fr -> Key.key(fr.id().toString()); + case FontDescription.AtlasSprite as -> Key.key(as.spriteId().toString()); + default -> throw new IllegalStateException("Unexpected value: " + description); + }; + } + // ------------------------ // ---- ChatType.Bound ---- // ------------------------ @@ -322,7 +332,7 @@ public static Component asAdventure(final net.minecraft.network.chat.Component c builder.append(SpongeAdventure.asAdventure(child)); } - builder.style(((org.spongepowered.common.bridge.network.chat.StyleBridge) component.getStyle()).bridge$asAdventure()); + builder.style(((org.spongepowered.common.bridge.network.chat.StyleBridge) (Object) component.getStyle()).bridge$asAdventure()); return builder.build(); } @@ -372,7 +382,7 @@ public static Component asAdventure(final net.minecraft.network.chat.Component c // no caching public static Style asAdventure(final net.minecraft.network.chat.Style mcStyle) { final Style.Builder builder = Style.style(); - final StyleAccessor $access = (StyleAccessor) mcStyle; + final StyleAccessor $access = (StyleAccessor) (Object) mcStyle; builder.font(SpongeAdventure.asAdventure($access.accessor$font())); // font builder.color(SpongeAdventure.asAdventure(mcStyle.getColor())); // color @@ -802,11 +812,18 @@ public static ResourceLocation asVanilla(final Key key) { return ResourceLocation.fromNamespaceAndPath(key.namespace(), key.value()); } - public static @Nullable ResourceLocation asVanillaNullable(final @Nullable Key key) { + public static @Nullable ResourceLocation asVanillaLocation(final @Nullable Key key) { + if (key == null) { + return null; + } + return ResourceLocation.fromNamespaceAndPath(key.namespace(), key.value()); + } + + public static @Nullable FontDescription asVanillaFontDescription(final @Nullable Key key) { if (key == null) { return null; } - return SpongeAdventure.asVanilla(key); + return new FontDescription.Resource(SpongeAdventure.asVanilla(key)); } // Sound diff --git a/src/main/java/org/spongepowered/common/ban/SpongeBanBuilder.java b/src/main/java/org/spongepowered/common/ban/SpongeBanBuilder.java index 19069c6a432..07534861ac7 100644 --- a/src/main/java/org/spongepowered/common/ban/SpongeBanBuilder.java +++ b/src/main/java/org/spongepowered/common/ban/SpongeBanBuilder.java @@ -123,7 +123,7 @@ public Ban build() { if (this.profile == null) { throw new IllegalStateException("User cannot be null"); } - return (Ban) new UserBanListEntry(SpongeGameProfile.toMcProfile(this.profile.withoutProperties()), + return (Ban) new UserBanListEntry(SpongeGameProfile.toNameAndId(this.profile.withoutProperties()), Date.from(this.start), sourceName, this.toDate(this.end), reason); } if (this.address == null) { diff --git a/src/main/java/org/spongepowered/common/bridge/server/level/ServerLevelBridge.java b/src/main/java/org/spongepowered/common/bridge/server/level/ServerLevelBridge.java index 18055be3d61..33344a4fd35 100644 --- a/src/main/java/org/spongepowered/common/bridge/server/level/ServerLevelBridge.java +++ b/src/main/java/org/spongepowered/common/bridge/server/level/ServerLevelBridge.java @@ -26,7 +26,6 @@ import net.minecraft.network.protocol.game.ClientboundExplodePacket; import net.minecraft.server.bossevents.CustomBossEvents; -import net.minecraft.server.level.progress.ChunkProgressListener; import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.world.level.storage.LevelStorageSource; import org.spongepowered.api.block.BlockSnapshot; @@ -36,8 +35,6 @@ public interface ServerLevelBridge { LevelStorageSource.LevelStorageAccess bridge$getLevelSave(); - ChunkProgressListener bridge$getChunkProgressListener(); - boolean bridge$isLoaded(); CustomBossEvents bridge$getBossBarManager(); diff --git a/src/main/java/org/spongepowered/common/command/parameter/managed/standard/SpongeGameProfileValueParameter.java b/src/main/java/org/spongepowered/common/command/parameter/managed/standard/SpongeGameProfileValueParameter.java index 3f770dd39e5..7a58ebe1168 100644 --- a/src/main/java/org/spongepowered/common/command/parameter/managed/standard/SpongeGameProfileValueParameter.java +++ b/src/main/java/org/spongepowered/common/command/parameter/managed/standard/SpongeGameProfileValueParameter.java @@ -31,6 +31,7 @@ import net.kyori.adventure.text.Component; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.GameProfileArgument; +import net.minecraft.server.players.NameAndId; import org.checkerframework.checker.nullness.qual.NonNull; import org.spongepowered.api.ResourceKey; import org.spongepowered.api.command.CommandCause; @@ -64,7 +65,7 @@ public CompletableFuture listSuggestions( public Optional parseValue( final @NonNull CommandCause cause, final ArgumentReader.@NonNull Mutable reader) throws ArgumentParseException { try { - final Collection profileCollection = + final Collection profileCollection = this.argument.parse((StringReader) reader).getNames((CommandSourceStack) cause); if (profileCollection.size() == 1) { return Optional.of(SpongeGameProfile.of(profileCollection.iterator().next())); diff --git a/src/main/java/org/spongepowered/common/data/provider/block/entity/BannerData.java b/src/main/java/org/spongepowered/common/data/provider/block/entity/BannerData.java index 7f1533ab577..18527783284 100644 --- a/src/main/java/org/spongepowered/common/data/provider/block/entity/BannerData.java +++ b/src/main/java/org/spongepowered/common/data/provider/block/entity/BannerData.java @@ -30,6 +30,7 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BannerBlockEntity; import net.minecraft.world.level.block.entity.BannerPatternLayers; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.data.Keys; import org.spongepowered.api.data.meta.BannerPatternLayer; import org.spongepowered.common.bridge.world.level.block.entity.BannerBlockEntityBridge; @@ -49,8 +50,8 @@ public static void register(final DataProviderRegistrator registrator) { .create(Keys.BANNER_PATTERN_LAYERS) .get(h -> h.getPatterns().layers().stream().map(BannerPatternLayer.class::cast).toList()) .setAnd((h, v) -> { - final Level world = h.getLevel(); - if (world != null && !world.isClientSide) { // This avoids a client crash because clientside. + final @Nullable Level world = h.getLevel(); + if (world != null && !world.isClientSide()) { // This avoids a client crash because clientside. applyBannerPatternLayers(h, v); return true; } diff --git a/src/main/java/org/spongepowered/common/data/provider/block/state/BlockStateDataProvider.java b/src/main/java/org/spongepowered/common/data/provider/block/state/BlockStateDataProvider.java index 924648252de..dd2d82f4c66 100644 --- a/src/main/java/org/spongepowered/common/data/provider/block/state/BlockStateDataProvider.java +++ b/src/main/java/org/spongepowered/common/data/provider/block/state/BlockStateDataProvider.java @@ -69,6 +69,7 @@ public static void register(final DataProviderRegistrator registrator) { BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CHISELED_BOOKSHELF_SLOT_4_OCCUPIED, BlockStateProperties.CHISELED_BOOKSHELF_SLOT_4_OCCUPIED); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CHISELED_BOOKSHELF_SLOT_5_OCCUPIED, BlockStateProperties.CHISELED_BOOKSHELF_SLOT_5_OCCUPIED); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CONDITIONAL, BlockStateProperties.CONDITIONAL); + BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.COPPER_GOLEM_POSE, BlockStateProperties.COPPER_GOLEM_POSE); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CRACKED, BlockStateProperties.CRACKED); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CRAFTING, BlockStateProperties.CRAFTING); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CREAKING_HEART_STATE, BlockStateProperties.CREAKING_HEART_STATE); @@ -139,6 +140,7 @@ public static void register(final DataProviderRegistrator registrator) { BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SEGMENT_AMOUNT, BlockStateProperties.SEGMENT_AMOUNT); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SHORT, BlockStateProperties.SHORT); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SHRIEKING, BlockStateProperties.SHRIEKING); + BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SIDE_CHAIN_PART, BlockStateProperties.SIDE_CHAIN_PART); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SIGNAL_FIRE, BlockStateProperties.SIGNAL_FIRE); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SLAB_TYPE, BlockStateProperties.SLAB_TYPE); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SNOWY, BlockStateProperties.SNOWY); diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/EntityData.java b/src/main/java/org/spongepowered/common/data/provider/entity/EntityData.java index 69937fac579..215697af97b 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/EntityData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/EntityData.java @@ -197,7 +197,7 @@ public static void register(final DataProviderRegistrator registrator) { .delete(Entity::ejectPassengers) .set((h, v) -> { h.ejectPassengers(); - v.forEach(v1 -> ((Entity) v1).startRiding(h, true)); + v.forEach(v1 -> ((Entity) v1).startRiding(h, true, true)); }) .create(Keys.PUSH_REACTION) .get(h -> (PushReaction) (Object) h.getPistonPushReaction()) @@ -224,7 +224,7 @@ public static void register(final DataProviderRegistrator registrator) { }) .create(Keys.VEHICLE) .get(h -> (org.spongepowered.api.entity.Entity) h.getVehicle()) - .set((h, v) -> h.startRiding((Entity) v, true)) + .set((h, v) -> h.startRiding((Entity) v, true, true)) .delete(h -> h.stopRiding()) .create(Keys.VELOCITY) .get(h -> VecHelper.toVector3d(h.getDeltaMovement())) diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/PaintingData.java b/src/main/java/org/spongepowered/common/data/provider/entity/PaintingData.java index ae6cb564d62..33b1260e63a 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/PaintingData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/PaintingData.java @@ -52,7 +52,7 @@ public static void register(final DataProviderRegistrator registrator) { .create(Keys.ART_TYPE) .get(h -> (ArtType) (Object) h.getVariant().value()) .setAnd((h, v) -> { - if (!h.level().isClientSide) { + if (!h.level().isClientSide()) { final Holder oldArt = h.getVariant(); var newArt = SpongeCommon.vanillaRegistry(Registries.PAINTING_VARIANT).wrapAsHolder((PaintingVariant) (Object) v); ((PaintingAccessor) h).invoker$setVariant(newArt); diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/VanishableData.java b/src/main/java/org/spongepowered/common/data/provider/entity/VanishableData.java index 4fb03550573..5a031072059 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/VanishableData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/VanishableData.java @@ -49,7 +49,7 @@ public static void register(final DataProviderRegistrator registrator) { .create(Keys.VANISH_STATE) .get(VanishableBridge::bridge$vanishState) .setAnd((h, v) -> { - if (h instanceof Entity && ((Entity) h).level().isClientSide) { + if (h instanceof Entity && ((Entity) h).level().isClientSide()) { return false; } h.bridge$vanishState(v); diff --git a/src/main/java/org/spongepowered/common/data/provider/item/stack/SignItemStackData.java b/src/main/java/org/spongepowered/common/data/provider/item/stack/SignItemStackData.java index 552e3c6c9c7..9560426e1c0 100644 --- a/src/main/java/org/spongepowered/common/data/provider/item/stack/SignItemStackData.java +++ b/src/main/java/org/spongepowered/common/data/provider/item/stack/SignItemStackData.java @@ -29,7 +29,8 @@ import net.minecraft.core.component.DataComponents; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.item.component.TypedEntityData; +import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.SignText; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.data.Keys; @@ -50,10 +51,11 @@ public static void register(final DataProviderRegistrator registrator) { .asMutable(ItemStack.class) .create(Keys.SIGN_LINES) .get(h -> { - final CompoundTag tag = h.getOrDefault(DataComponents.BLOCK_ENTITY_DATA, CustomData.EMPTY).copyTag(); - if (tag.isEmpty()) { + final @Nullable TypedEntityData data = h.get(DataComponents.BLOCK_ENTITY_DATA); + if (data == null) { return null; } + final var tag = data.getUnsafe(); final String id = tag.getStringOr(Constants.Item.BLOCK_ENTITY_ID, ""); if (!id.equalsIgnoreCase(Constants.TileEntity.SIGN)) { @@ -76,7 +78,7 @@ public static void register(final DataProviderRegistrator registrator) { } tag.putString("Text" + (i + 1), gcs.serialize(line)); } - h.set(DataComponents.BLOCK_ENTITY_DATA, CustomData.of(tag)); + h.set(DataComponents.BLOCK_ENTITY_DATA, TypedEntityData.of(BlockEntityType.SIGN, tag)); }) .delete(h -> h.remove(DataComponents.BLOCK_ENTITY_DATA)); } diff --git a/src/main/java/org/spongepowered/common/data/provider/item/stack/SpawnEggItemStackData.java b/src/main/java/org/spongepowered/common/data/provider/item/stack/SpawnEggItemStackData.java index 81f7b503cb3..aa2c98f0a1b 100644 --- a/src/main/java/org/spongepowered/common/data/provider/item/stack/SpawnEggItemStackData.java +++ b/src/main/java/org/spongepowered/common/data/provider/item/stack/SpawnEggItemStackData.java @@ -25,11 +25,14 @@ package org.spongepowered.common.data.provider.item.stack; import net.minecraft.core.component.DataComponents; +import net.minecraft.nbt.CompoundTag; import net.minecraft.world.entity.EntityType; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.SpawnEggItem; import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.item.component.TypedEntityData; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.data.Keys; import org.spongepowered.api.entity.EntityArchetype; import org.spongepowered.common.SpongeCommon; @@ -47,11 +50,14 @@ public static void register(final DataProviderRegistrator registrator) { .get(stack -> { final Item item = stack.getItem(); final SpawnEggItem eggItem = (SpawnEggItem) item; - final EntityType type = eggItem.getType(SpongeCommon.vanillaRegistryAccess(), stack); - final var tag = stack.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY).getUnsafe(); + final @Nullable EntityType type = eggItem.getType(stack); + if (type == null) { + return null; + } + final var data = stack.getOrDefault(DataComponents.ENTITY_DATA, TypedEntityData.of(type, new CompoundTag())); final EntityArchetype.Builder builder = EntityArchetype.builder().type((org.spongepowered.api.entity.EntityType) type); - ((SpongeEntityArchetypeBuilder)builder).entityData(tag); + ((SpongeEntityArchetypeBuilder)builder).entityData(data.copyTagWithoutId()); return builder.build(); }) @@ -61,7 +67,7 @@ public static void register(final DataProviderRegistrator registrator) { .get(stack -> { final Item item = stack.getItem(); final SpawnEggItem eggItem = (SpawnEggItem) item; - return (org.spongepowered.api.entity.EntityType) eggItem.getType(SpongeCommon.vanillaRegistryAccess(), stack); + return (org.spongepowered.api.entity.EntityType) eggItem.getType(stack); }) ; } diff --git a/src/main/java/org/spongepowered/common/effect/util/ViewerPacketUtil.java b/src/main/java/org/spongepowered/common/effect/util/ViewerPacketUtil.java index a8cfbed2216..e59feb0d429 100644 --- a/src/main/java/org/spongepowered/common/effect/util/ViewerPacketUtil.java +++ b/src/main/java/org/spongepowered/common/effect/util/ViewerPacketUtil.java @@ -102,7 +102,7 @@ public static ClientboundSoundPacket playSound(final Sound sound, final RandomSo public static ClientboundStopSoundPacket stopSound(final SoundStop stop) { Objects.requireNonNull(stop, "stop"); - final @Nullable ResourceLocation sound = SpongeAdventure.asVanillaNullable(stop.sound()); + final @Nullable ResourceLocation sound = SpongeAdventure.asVanillaLocation(stop.sound()); final @Nullable SoundSource source = SpongeAdventure.asVanillaNullable(stop.source()); return new ClientboundStopSoundPacket(sound, source); } diff --git a/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java b/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java index e96f11ea028..28ee38978fc 100644 --- a/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java +++ b/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java @@ -46,6 +46,7 @@ import net.minecraft.server.level.ServerEntity; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.players.NameAndId; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; import net.minecraft.util.Mth; @@ -310,22 +311,22 @@ private void setProfileName(final net.minecraft.network.chat.@Nullable Component } public boolean getOrLoadSkin(final UUID minecraftAccount) { - GameProfile gameProfile = SpongeCommon.server().getProfileCache().get(minecraftAccount).orElse(null); - if (gameProfile == null) { - ProfileResult result = - SpongeCommon.server().getSessionService().fetchProfile(minecraftAccount, true); + final var server = SpongeCommon.server(); + final @Nullable GameProfile profile = server.nameToIdCache().get(minecraftAccount).flatMap(name -> + server.getProfileRepository().findProfileByName(name.name()) + ).orElseGet(() -> { + final @Nullable ProfileResult result = server.getSessionService().fetchProfile(minecraftAccount, true); if (result == null) { - return false; + return null; } - - gameProfile = result.profile(); - - // TODO Should we put profile cache entries with UUIDs that don't have their names? - - SpongeCommon.server().getProfileCache().add(gameProfile); + server.nameToIdCache().add(new NameAndId(result.profile())); + return result.profile(); + }); + if (profile == null) { + return false; } - this.fakeProfile.properties().replaceValues(ProfileProperty.TEXTURES, gameProfile.getProperties().get(ProfileProperty.TEXTURES)); + this.fakeProfile.properties().replaceValues(ProfileProperty.TEXTURES, profile.getProperties().get(ProfileProperty.TEXTURES)); if (this.isAliveAndInWorld()) { this.respawnOnClient(); } @@ -335,22 +336,16 @@ public boolean getOrLoadSkin(final UUID minecraftAccount) { public boolean getOrLoadSkin(final String minecraftAccount) { Objects.requireNonNull(minecraftAccount); - GameProfile gameProfile = SpongeCommon.server().getProfileCache().get(minecraftAccount).orElse(null); - if (gameProfile == null) { + final var server = SpongeCommon.server(); + final @Nullable GameProfile profile = server.nameToIdCache().get(minecraftAccount).flatMap(name -> + server.getProfileRepository().findProfileByName(name.name()) + ).orElse(null); + if (profile == null) { return false; } - if (gameProfile.getProperties().isEmpty()) { - ProfileResult result = SpongeCommon.server().getSessionService().fetchProfile(gameProfile.getId(), true); - if (result == null) { - return false; - } - gameProfile = result.profile(); - SpongeCommon.server().getProfileCache().add(gameProfile); - } - this.fakeProfile.properties().clear(); - this.fakeProfile.properties().putAll(gameProfile.getProperties()); + this.fakeProfile.properties().putAll(profile.getProperties()); if (this.isAliveAndInWorld()) { this.respawnOnClient(); } diff --git a/src/main/java/org/spongepowered/common/event/SpongeCommonEventFactory.java b/src/main/java/org/spongepowered/common/event/SpongeCommonEventFactory.java index 4d694340aeb..3c1ca2c8de5 100644 --- a/src/main/java/org/spongepowered/common/event/SpongeCommonEventFactory.java +++ b/src/main/java/org/spongepowered/common/event/SpongeCommonEventFactory.java @@ -518,10 +518,6 @@ public enum CollisionType public static boolean handleCollideBlockEvent(final Block block, final Level world, final BlockPos pos, final net.minecraft.world.level.block.state.BlockState state, final net.minecraft.world.entity.Entity entity, final Direction direction, final CollisionType type) { - if (world.isClientSide) { - return false; - } - if (world.isClientSide() || pos.getY() < world.getMinY()) { return false; } @@ -529,30 +525,23 @@ public static boolean handleCollideBlockEvent(final Block block, final Level wor try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) { frame.pushCause(entity); - if (entity instanceof CreatorTrackedBridge) { - final CreatorTrackedBridge spongeEntity = (CreatorTrackedBridge) entity; + if (entity instanceof CreatorTrackedBridge spongeEntity) { spongeEntity.tracker$getCreatorUUID().ifPresent(user -> frame.addContext(EventContextKeys.CREATOR, user)); } // TODO: Add target side support final ServerLocation loc = ServerLocation.of((ServerWorld) world, VecHelper.toVector3d(pos)); - final CollideBlockEvent event; - switch (type) { - case MOVE: - event = SpongeEventFactory.createCollideBlockEventMove(frame.currentCause(), (BlockState) state, loc, direction); - break; - case FALL: - event = SpongeEventFactory.createCollideBlockEventFall(frame.currentCause(), (BlockState) state, loc, direction); - break; - case STEP_ON: - event = SpongeEventFactory.createCollideBlockEventStepOn(frame.currentCause(), (BlockState) state, loc, direction); - break; - case INSIDE: - event = SpongeEventFactory.createCollideBlockEventInside(frame.currentCause(), (BlockState) state, loc, direction); - break; - default: - throw new IllegalArgumentException("Unknown type " + type); - } + final CollideBlockEvent event = switch (type) { + case MOVE -> + SpongeEventFactory.createCollideBlockEventMove(frame.currentCause(), (BlockState) state, loc, direction); + case FALL -> + SpongeEventFactory.createCollideBlockEventFall(frame.currentCause(), (BlockState) state, loc, direction); + case STEP_ON -> + SpongeEventFactory.createCollideBlockEventStepOn(frame.currentCause(), (BlockState) state, loc, direction); + case INSIDE -> + SpongeEventFactory.createCollideBlockEventInside(frame.currentCause(), (BlockState) state, loc, direction); + default -> throw new IllegalArgumentException("Unknown type " + type); + }; final boolean cancelled = SpongeCommon.post(event); if (!cancelled) { final EntityBridge spongeEntity = (EntityBridge) entity; diff --git a/src/main/java/org/spongepowered/common/event/tracking/phase/tick/EntityTickPhaseState.java b/src/main/java/org/spongepowered/common/event/tracking/phase/tick/EntityTickPhaseState.java index 962b8c0cbd2..a370479c4dd 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/phase/tick/EntityTickPhaseState.java +++ b/src/main/java/org/spongepowered/common/event/tracking/phase/tick/EntityTickPhaseState.java @@ -110,7 +110,7 @@ public Supplier attemptWorldKey( final net.minecraft.world.entity.Entity entity = context.getSource(net.minecraft.world.entity.Entity.class) .orElseThrow( () -> new IllegalStateException("Expected to be ticking an entity, but we're not ticking an entity")); - if (entity.level().isClientSide) { + if (entity.level().isClientSide()) { return () -> { throw new IllegalStateException("attempting a world key on the client???"); }; diff --git a/src/main/java/org/spongepowered/common/inventory/custom/CarriedWrapperInventory.java b/src/main/java/org/spongepowered/common/inventory/custom/CarriedWrapperInventory.java index d31b8dd6218..2797832abe3 100644 --- a/src/main/java/org/spongepowered/common/inventory/custom/CarriedWrapperInventory.java +++ b/src/main/java/org/spongepowered/common/inventory/custom/CarriedWrapperInventory.java @@ -104,16 +104,6 @@ public boolean stillValid(Player player) { return this.wrapped.stillValid(player); } - @Override - public void startOpen(Player player) { - this.wrapped.startOpen(player); - } - - @Override - public void stopOpen(Player player) { - this.wrapped.stopOpen(player); - } - @Override public boolean canPlaceItem(int index, ItemStack stack) { return this.wrapped.canPlaceItem(index, stack); @@ -133,4 +123,5 @@ public boolean hasAnyOf(Set set) { public void clearContent() { this.wrapped.clearContent(); } + } diff --git a/src/main/java/org/spongepowered/common/inventory/custom/ViewableCustomInventory.java b/src/main/java/org/spongepowered/common/inventory/custom/ViewableCustomInventory.java index a62ffd5c089..59ebaf67625 100644 --- a/src/main/java/org/spongepowered/common/inventory/custom/ViewableCustomInventory.java +++ b/src/main/java/org/spongepowered/common/inventory/custom/ViewableCustomInventory.java @@ -76,16 +76,6 @@ public ContainerType getType() { return this.type; } - @Override - public void startOpen(final Player player) { - this.viewers.add(player); // TODO check if this is always called - } - - @Override - public void stopOpen(final Player player) { - this.viewers.remove(player); // TODO check if this is always called - } - @Override public @Nullable AbstractContainerMenu createMenu(int id, net.minecraft.world.entity.player.Inventory playerInv, Player player) { if (this.vanilla) { diff --git a/src/main/java/org/spongepowered/common/item/SpongeItemStack.java b/src/main/java/org/spongepowered/common/item/SpongeItemStack.java index ced0b591832..b11fb94a437 100644 --- a/src/main/java/org/spongepowered/common/item/SpongeItemStack.java +++ b/src/main/java/org/spongepowered/common/item/SpongeItemStack.java @@ -28,6 +28,7 @@ import com.google.common.collect.ImmutableList; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Dynamic; +import net.minecraft.core.Registry; import net.minecraft.core.component.DataComponentPatch; import net.minecraft.core.component.DataComponentType; import net.minecraft.core.component.DataComponents; @@ -43,7 +44,9 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.component.CustomData; import net.minecraft.world.item.component.ItemAttributeModifiers; +import net.minecraft.world.item.component.TypedEntityData; import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntityType; import org.checkerframework.checker.nullness.qual.Nullable; import org.jetbrains.annotations.NotNull; import org.spongepowered.api.block.BlockSnapshot; @@ -76,7 +79,7 @@ import java.util.Objects; import java.util.Optional; -public final class SpongeItemStack { +public final class SpongeItemStack { public static final class BuilderImpl extends AbstractDataBuilder implements ItemStack.Builder { private ItemType type; @@ -195,9 +198,16 @@ public ItemStack.Builder fromBlockSnapshot(final BlockSnapshot blockSnapshot) { final Optional itemType = blockType.item(); this.itemType(itemType.orElseThrow(() -> new IllegalArgumentException("ItemType not found for block type: " + blockTypeKey))); this.quantity(1); - if (blockSnapshot instanceof SpongeBlockSnapshot) { - ((SpongeBlockSnapshot) blockSnapshot).getCompound().ifPresent(compoundTag -> { - this.components = DataComponentPatch.builder().set(DataComponents.BLOCK_ENTITY_DATA, CustomData.of(compoundTag)).build(); + if (blockSnapshot instanceof SpongeBlockSnapshot sbs) { + sbs.getCompound().ifPresent(compoundTag -> { + final var blockEntityTypes = SpongeCommon.vanillaRegistry(Registries.BLOCK_ENTITY_TYPE); + final var blockEntityType = compoundTag.getString("id") + .map(ResourceLocation::parse) + .flatMap(blockEntityTypes::getOptional); + blockEntityType.ifPresent(beType -> { + TypedEntityData> data = TypedEntityData.of(beType, compoundTag); + this.components = DataComponentPatch.builder().set(DataComponents.BLOCK_ENTITY_DATA, data).build(); + }); }); // todo probably needs more testing, but this'll do donkey... @@ -275,9 +285,9 @@ public ItemStack empty() { public static DataContainer getDataContainer(final net.minecraft.world.item.ItemStack mcStack) { final ResourceLocation key = BuiltInRegistries.ITEM.getKey(mcStack.getItem()); final DataContainer container = DataContainer.createNew() - .set(Queries.CONTENT_VERSION, ((ItemStack) (Object) mcStack).contentVersion()) - .set(Constants.ItemStack.TYPE, key) - .set(Constants.ItemStack.COUNT, mcStack.getCount()); + .set(Queries.CONTENT_VERSION, ((ItemStack) (Object) mcStack).contentVersion()) + .set(Constants.ItemStack.TYPE, key) + .set(Constants.ItemStack.COUNT, mcStack.getCount()); // Cleanup Old Custom Data SpongeItemStack.cleanupOldCustomData(mcStack); // Serialize all DataComponents... @@ -305,15 +315,16 @@ public static EquipmentSlotGroup asEquipmentSlotGroup(final EquipmentType equipm @SuppressWarnings("deprecation") private static void cleanupOldCustomData(final net.minecraft.world.item.ItemStack stack) { - final CompoundTag unsafe = stack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).getUnsafe(); - unsafe.remove(Constants.Sponge.Data.V2.SPONGE_DATA); // and its V2.CUSTOM_MANIPULATOR_TAG_LIST - Constants.NBT.filterSpongeCustomData(unsafe); // FORGE_DATA > V2.SPONGE_DATA also removes it if empty + stack.update(DataComponents.CUSTOM_DATA, CustomData.EMPTY, data -> data.update(tag -> { + tag.remove(Constants.Sponge.Data.V2.SPONGE_DATA); // and its V2.CUSTOM_MANIPULATOR_TAG_LIST + Constants.NBT.filterSpongeCustomData(tag); // FORGE_DATA > V2.SPONGE_DATA also removes it if empty + })); } // TODO updater for old (maybe V2?) Constants.Sponge.DATA_MANIPULATORS public static final ImmutableList STACK_UPDATERS = ImmutableList.of( - ItemStackSnapshotDuplicateManipulatorUpdater.INSTANCE, - ItemStackDataComponentsUpdater.INSTANCE); + ItemStackSnapshotDuplicateManipulatorUpdater.INSTANCE, + ItemStackDataComponentsUpdater.INSTANCE); @NotNull public static Optional createItemStack(final DataView container) { @@ -341,7 +352,7 @@ public static Optional createItemStack(final DataView container) { final int count = updatedContainer.getInt(Constants.ItemStack.COUNT).get(); final ItemType itemType = updatedContainer.getRegistryValue(Constants.ItemStack.TYPE, RegistryTypes.ITEM_TYPE) - .orElseThrow(() -> new IllegalStateException("Unable to find item with id: ")); + .orElseThrow(() -> new IllegalStateException("Unable to find item with id: ")); final var mcStack = new net.minecraft.world.item.ItemStack((Item) itemType, count); if (!mcStack.isEmpty()) { // ignore components when the stack is empty anyways // Read and apply components from container to mc stack diff --git a/src/main/java/org/spongepowered/common/network/packet/SpongePacketHandler.java b/src/main/java/org/spongepowered/common/network/packet/SpongePacketHandler.java index ed0bf11cd26..d8798e4b23f 100644 --- a/src/main/java/org/spongepowered/common/network/packet/SpongePacketHandler.java +++ b/src/main/java/org/spongepowered/common/network/packet/SpongePacketHandler.java @@ -24,13 +24,13 @@ */ package org.spongepowered.common.network.packet; -import com.mojang.authlib.GameProfile; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.DimensionSpecialEffects; import net.minecraft.core.BlockPos; import net.minecraft.core.SectionPos; import net.minecraft.core.registries.Registries; +import net.minecraft.server.players.NameAndId; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.dimension.DimensionType; import org.spongepowered.api.ResourceKey; @@ -110,11 +110,11 @@ private static TrackerDataResponsePacket createTrackerDataResponse( final Optional owner, final Optional notifier ) { - final String ownerName = owner.flatMap(x -> SpongeCommon.server().getProfileCache().get(x)) - .map(GameProfile::getName) + final String ownerName = owner.flatMap(SpongeCommon.server().nameToIdCache()::get) + .map(NameAndId::name) .orElse(""); - final String notifierName = notifier.flatMap(x -> SpongeCommon.server().getProfileCache().get(x)) - .map(GameProfile::getName) + final String notifierName = notifier.flatMap(SpongeCommon.server().nameToIdCache()::get) + .map(NameAndId::name) .orElse(""); return new TrackerDataResponsePacket(ownerName, notifierName); } diff --git a/src/main/java/org/spongepowered/common/profile/SpongeGameProfile.java b/src/main/java/org/spongepowered/common/profile/SpongeGameProfile.java index 1671fe3d08c..7c75e137602 100644 --- a/src/main/java/org/spongepowered/common/profile/SpongeGameProfile.java +++ b/src/main/java/org/spongepowered/common/profile/SpongeGameProfile.java @@ -27,6 +27,7 @@ import com.google.common.collect.ImmutableList; import com.google.gson.Gson; import com.google.gson.JsonObject; +import net.minecraft.server.players.NameAndId; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.data.persistence.DataContainer; @@ -54,6 +55,12 @@ public final class SpongeGameProfile implements GameProfile { private static final Gson GSON = new Gson(); public static final UUID EMPTY_UUID = new UUID(0, 0); + public static SpongeGameProfile of(NameAndId mcProfile) { + final UUID uniqueId = mcProfile.id(); + final var name = mcProfile.name().isEmpty() ? null : mcProfile.name(); + return new SpongeGameProfile(uniqueId, name); + } + public static SpongeGameProfile of(final com.mojang.authlib.GameProfile mcProfile) { final UUID uniqueId = mcProfile.getId(); final String name = mcProfile.getName().isEmpty() ? null : mcProfile.getName(); @@ -63,12 +70,21 @@ public static SpongeGameProfile of(final com.mojang.authlib.GameProfile mcProfil return new SpongeGameProfile(uniqueId, name, properties); } + public static SpongeGameProfile basicOf(final NameAndId mcProfile) { + final var name = mcProfile.name().isEmpty() ? null : mcProfile.name(); + return new SpongeGameProfile(mcProfile.id(), name); + } + public static SpongeGameProfile basicOf(final com.mojang.authlib.GameProfile mcProfile) { final UUID uniqueId = mcProfile.getId(); final String name = mcProfile.getName().isEmpty() ? null : mcProfile.getName(); return new SpongeGameProfile(uniqueId, name); } + public static NameAndId toNameAndId(final GameProfile profile) { + return new NameAndId(profile.uuid(), profile.name().orElse("")); + } + public static com.mojang.authlib.GameProfile toMcProfile(final GameProfile profile) { return ((SpongeGameProfile) profile).toMcProfile(); } diff --git a/src/main/java/org/spongepowered/common/profile/SpongeGameProfileManager.java b/src/main/java/org/spongepowered/common/profile/SpongeGameProfileManager.java index f9ea16c603b..49fbc37b122 100644 --- a/src/main/java/org/spongepowered/common/profile/SpongeGameProfileManager.java +++ b/src/main/java/org/spongepowered/common/profile/SpongeGameProfileManager.java @@ -67,7 +67,7 @@ public final class SpongeGameProfileManager implements GameProfileManager { public SpongeGameProfileManager(final Server server) { this.usernameCache = ((SpongeServer) server).getUsernameCache(); - this.cache = (GameProfileCacheBridge) ((MinecraftServer) server).getProfileCache(); + this.cache = (GameProfileCacheBridge) ((MinecraftServer) server).nameToIdCache(); this.gameLookupExecutorService = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder() .setNameFormat("Sponge - Async User Lookup Thread").build()); } diff --git a/src/main/java/org/spongepowered/common/service/server/ban/SpongeBanService.java b/src/main/java/org/spongepowered/common/service/server/ban/SpongeBanService.java index d2779bc6e82..4b160a73533 100644 --- a/src/main/java/org/spongepowered/common/service/server/ban/SpongeBanService.java +++ b/src/main/java/org/spongepowered/common/service/server/ban/SpongeBanService.java @@ -27,6 +27,7 @@ import com.google.inject.Singleton; import net.minecraft.server.players.IpBanList; import net.minecraft.server.players.IpBanListEntry; +import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.StoredUserEntry; import net.minecraft.server.players.UserBanList; import net.minecraft.server.players.UserBanListEntry; @@ -78,8 +79,8 @@ public CompletableFuture> bans() { @SuppressWarnings("unchecked") @Override public CompletableFuture> profileBans() { - final StoredUserListAccessor accessor = - (StoredUserListAccessor) this.getUserBanList(); + final StoredUserListAccessor accessor = + (StoredUserListAccessor) this.getUserBanList(); accessor.invoker$removeExpired(); return CompletableFuture.completedFuture(Collections.unmodifiableCollection(new ArrayList<>((Collection) (Object) accessor.accessor$map().values()))); } @@ -87,7 +88,7 @@ public CompletableFuture> profileBans() { @SuppressWarnings("unchecked") @Override public CompletableFuture> ipBans() { - final StoredUserListAccessor accessor = ((StoredUserListAccessor) this.getIPBanList()); + final StoredUserListAccessor accessor = ((StoredUserListAccessor) this.getIPBanList()); accessor.invoker$removeExpired(); return CompletableFuture.completedFuture(Collections.unmodifiableCollection(new ArrayList<>((Collection) (Object) accessor.accessor$map().values()))); } @@ -95,10 +96,10 @@ public CompletableFuture> ipBans() { @SuppressWarnings("unchecked") @Override public CompletableFuture> find(final GameProfile profile) { - final StoredUserListAccessor accessor = - (StoredUserListAccessor) this.getUserBanList(); + final StoredUserListAccessor accessor = + (StoredUserListAccessor) this.getUserBanList(); accessor.invoker$removeExpired(); - return CompletableFuture.completedFuture(Optional.ofNullable((Ban.Profile) accessor.accessor$map().get(accessor.invoker$getKeyForUser(SpongeGameProfile.toMcProfile(profile))))); + return CompletableFuture.completedFuture(Optional.ofNullable((Ban.Profile) accessor.accessor$map().get(accessor.invoker$getKeyForUser(SpongeGameProfile.toNameAndId(profile))))); } @SuppressWarnings("unchecked") @@ -112,11 +113,11 @@ public CompletableFuture> find(final InetAddress address) { @SuppressWarnings("unchecked") public boolean isBanned(final GameProfile profile) { - final StoredUserListAccessor accessor = - (StoredUserListAccessor) this.getUserBanList(); + final StoredUserListAccessor accessor = + (StoredUserListAccessor) this.getUserBanList(); accessor.invoker$removeExpired(); - return accessor.accessor$map().containsKey(accessor.invoker$getKeyForUser(SpongeGameProfile.toMcProfile(profile))); + return accessor.accessor$map().containsKey(accessor.invoker$getKeyForUser(SpongeGameProfile.toNameAndId(profile))); } @SuppressWarnings("unchecked") @@ -131,8 +132,8 @@ public boolean isBanned(final InetAddress address) { @Override public CompletableFuture pardon(final GameProfile profile) { final CompletableFuture> ban = this.find(profile); - final StoredUserListAccessor accessor = - (StoredUserListAccessor) this.getUserBanList(); + final StoredUserListAccessor accessor = + (StoredUserListAccessor) this.getUserBanList(); accessor.invoker$removeExpired(); return ban.thenCompose(result -> result.map(this::remove).orElse(CompletableFuture.completedFuture(false))); } diff --git a/src/main/java/org/spongepowered/common/service/server/ban/SpongeUserBanList.java b/src/main/java/org/spongepowered/common/service/server/ban/SpongeUserBanList.java index 85e8b0d61f8..35ca1c9575a 100644 --- a/src/main/java/org/spongepowered/common/service/server/ban/SpongeUserBanList.java +++ b/src/main/java/org/spongepowered/common/service/server/ban/SpongeUserBanList.java @@ -25,6 +25,7 @@ package org.spongepowered.common.service.server.ban; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.UserBanList; import net.minecraft.server.players.UserBanListEntry; import org.spongepowered.api.Sponge; @@ -51,19 +52,19 @@ public SpongeUserBanList(final File file) { } @Override - protected boolean contains(final com.mojang.authlib.GameProfile profile) { + protected boolean contains(final NameAndId profile) { return Sponge.server().serviceProvider().banService().find(SpongeGameProfile.of(profile)).join().isPresent(); } @Override - public UserBanListEntry get(final com.mojang.authlib.GameProfile profile) { + public UserBanListEntry get(final NameAndId profile) { final Optional ban = Sponge.server().serviceProvider().banService().find(SpongeGameProfile.of(profile)).join(); return ban.map(x -> { if (x instanceof UserBanListEntry) { return (UserBanListEntry) x; } else { final LegacyComponentSerializer lcs = LegacyComponentSerializer.legacySection(); - return new UserBanListEntry(SpongeGameProfile.toMcProfile(x.profile()), + return new UserBanListEntry(SpongeGameProfile.toNameAndId(x.profile()), Date.from(x.creationDate()), x.banSource().map(lcs::serialize).orElse(null), x.expirationDate().map(Date::from).orElse(null), @@ -94,7 +95,7 @@ public boolean isEmpty() { } @Override - public void remove(final com.mojang.authlib.GameProfile entry) { + public void remove(final NameAndId entry) { final CompletableFuture completableFuture = Sponge.server().serviceProvider().banService().pardon(SpongeGameProfile.of(entry)); ((MinecraftServerBridge) SpongeCommon.server()).bridge$spongeMainThreadExecutor().managedBlock(completableFuture::isDone); } diff --git a/src/main/java/org/spongepowered/common/service/server/permission/UserCollection.java b/src/main/java/org/spongepowered/common/service/server/permission/UserCollection.java index 803e57f8ea1..3d9ba6409a3 100644 --- a/src/main/java/org/spongepowered/common/service/server/permission/UserCollection.java +++ b/src/main/java/org/spongepowered/common/service/server/permission/UserCollection.java @@ -25,6 +25,7 @@ package org.spongepowered.common.service.server.permission; import com.mojang.authlib.GameProfile; +import net.minecraft.server.players.NameAndId; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.Sponge; import org.spongepowered.api.service.permission.PermissionService; @@ -73,8 +74,7 @@ public boolean isRegistered(final String identifier) { return false; } // Name doesn't matter when getting entries - final GameProfile profile = new GameProfile(uuid, ""); - return SpongePermissionService.getOps().get(profile) != null; + return SpongePermissionService.getOps().get(new NameAndId(uuid, "")) != null; } private @Nullable UUID identityToUuid(final String identifier) { diff --git a/src/main/java/org/spongepowered/common/service/server/permission/UserSubject.java b/src/main/java/org/spongepowered/common/service/server/permission/UserSubject.java index 62637f1ba03..df90e34cd52 100644 --- a/src/main/java/org/spongepowered/common/service/server/permission/UserSubject.java +++ b/src/main/java/org/spongepowered/common/service/server/permission/UserSubject.java @@ -25,6 +25,7 @@ package org.spongepowered.common.service.server.permission; import com.mojang.authlib.GameProfile; +import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.ServerOpListEntry; import org.spongepowered.api.Sponge; import org.spongepowered.api.event.Cause; @@ -43,11 +44,13 @@ */ public class UserSubject extends SpongeSubject { private final GameProfile player; + private final NameAndId nameAndId; private final MemorySubjectData data; private final UserCollection collection; public UserSubject(final GameProfile player, final UserCollection users) { this.player = Objects.requireNonNull(player); + this.nameAndId = new NameAndId(player); this.data = new SingleParentMemorySubjectData(this) { @Override public SubjectReference parent() { @@ -67,9 +70,9 @@ public void setParent(final SubjectReference parent) { } if (opLevel > 0) { // TODO: Should bypassesPlayerLimit be true or false? - SpongePermissionService.getOps().add(new ServerOpListEntry(player, opLevel, false)); + SpongePermissionService.getOps().add(new ServerOpListEntry(UserSubject.this.nameAndId, opLevel, false)); } else { - SpongePermissionService.getOps().remove(player); + SpongePermissionService.getOps().remove(UserSubject.this.nameAndId); } } }; @@ -100,10 +103,10 @@ int getOpLevel() { Preconditions.checkState(Sponge.isServerAvailable(), "Server is not available!"); // Query op level from server ops list based on player's game profile - final ServerOpListEntry entry = SpongePermissionService.getOps().get(this.player); + final ServerOpListEntry entry = SpongePermissionService.getOps().get(this.nameAndId); if (entry == null) { // Take care of singleplayer commands -- unless an op level is specified, this player follows global rules - return SpongeCommon.server().getPlayerList().isOp(this.player) ? SpongeCommon.server().getOperatorUserPermissionLevel() : 0; + return SpongeCommon.server().getPlayerList().isOp(this.nameAndId) ? SpongeCommon.server().getOperatorUserPermissionLevel() : 0; } else { return entry.getLevel(); } diff --git a/src/main/java/org/spongepowered/common/service/server/whitelist/SpongeUserWhiteList.java b/src/main/java/org/spongepowered/common/service/server/whitelist/SpongeUserWhiteList.java index 7b450b45d77..694aacc02c8 100644 --- a/src/main/java/org/spongepowered/common/service/server/whitelist/SpongeUserWhiteList.java +++ b/src/main/java/org/spongepowered/common/service/server/whitelist/SpongeUserWhiteList.java @@ -24,6 +24,7 @@ */ package org.spongepowered.common.service.server.whitelist; +import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.UserWhiteList; import net.minecraft.server.players.UserWhiteListEntry; import org.spongepowered.api.Sponge; @@ -46,7 +47,7 @@ public SpongeUserWhiteList(final File file) { } @Override - protected boolean contains(final com.mojang.authlib.GameProfile entry) { + protected boolean contains(final NameAndId entry) { return Sponge.server().serviceProvider().whitelistService().isWhitelisted(SpongeGameProfile.of(entry)).join(); } @@ -66,7 +67,7 @@ public void add(final UserWhiteListEntry entry) { } @Override - public void remove(final com.mojang.authlib.GameProfile entry) { + public void remove(final NameAndId entry) { Sponge.server().serviceProvider().whitelistService().removeProfile(SpongeGameProfile.of(entry)).join(); } diff --git a/src/main/java/org/spongepowered/common/service/server/whitelist/SpongeWhitelistService.java b/src/main/java/org/spongepowered/common/service/server/whitelist/SpongeWhitelistService.java index 337852b75ca..dd9d59dfc12 100644 --- a/src/main/java/org/spongepowered/common/service/server/whitelist/SpongeWhitelistService.java +++ b/src/main/java/org/spongepowered/common/service/server/whitelist/SpongeWhitelistService.java @@ -25,6 +25,7 @@ package org.spongepowered.common.service.server.whitelist; import com.google.inject.Singleton; +import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.UserWhiteList; import net.minecraft.server.players.UserWhiteListEntry; import org.spongepowered.api.profile.GameProfile; @@ -49,8 +50,8 @@ public CompletableFuture> whitelistedProfiles() { final List profiles = new ArrayList<>(); final UserWhiteList list = SpongeCommon.server().getPlayerList().getWhiteList(); - for (final UserWhiteListEntry entry: ((StoredUserListAccessor) list).accessor$map().values()) { - profiles.add(SpongeGameProfile.of(((StoredUserEntryAccessor) entry).accessor$user())); + for (final UserWhiteListEntry entry: ((StoredUserListAccessor) list).accessor$map().values()) { + profiles.add(SpongeGameProfile.of(((StoredUserEntryAccessor) entry).accessor$user())); } return CompletableFuture.completedFuture(profiles); @@ -59,16 +60,16 @@ public CompletableFuture> whitelistedProfiles() { @SuppressWarnings("unchecked") @Override public CompletableFuture isWhitelisted(final GameProfile profile) { - final StoredUserListAccessor whitelist = (StoredUserListAccessor) SpongeWhitelistService + final StoredUserListAccessor whitelist = (StoredUserListAccessor) SpongeWhitelistService .getWhitelist(); whitelist.invoker$removeExpired(); - return CompletableFuture.completedFuture(whitelist.accessor$map().containsKey(whitelist.invoker$getKeyForUser(SpongeGameProfile.toMcProfile(profile)))); + return CompletableFuture.completedFuture(whitelist.accessor$map().containsKey(whitelist.invoker$getKeyForUser(SpongeGameProfile.toNameAndId(profile)))); } @Override public CompletableFuture addProfile(final GameProfile profile) { - final boolean wasWhitelisted = UserListUtil.addEntry(SpongeWhitelistService.getWhitelist(), new UserWhiteListEntry(SpongeGameProfile.toMcProfile(profile))) != null; + final boolean wasWhitelisted = UserListUtil.addEntry(SpongeWhitelistService.getWhitelist(), new UserWhiteListEntry(SpongeGameProfile.toNameAndId(profile))) != null; return CompletableFuture.completedFuture(wasWhitelisted); } diff --git a/src/main/java/org/spongepowered/common/user/SpongeUserManager.java b/src/main/java/org/spongepowered/common/user/SpongeUserManager.java index 60b7c4e369d..08445d2b1ff 100644 --- a/src/main/java/org/spongepowered/common/user/SpongeUserManager.java +++ b/src/main/java/org/spongepowered/common/user/SpongeUserManager.java @@ -112,7 +112,8 @@ public CompletableFuture loadOrCreate(final UUID uuid) { return CompletableFuture.completedFuture(null); } return CompletableFuture.supplyAsync(() -> { - final com.mojang.authlib.GameProfile profile = this.server.getProfileCache().get(uuidToUse) + final com.mojang.authlib.GameProfile profile = this.server.nameToIdCache().get(uuidToUse) + .map(nameAndId -> new com.mojang.authlib.GameProfile(nameAndId.id(), nameAndId.name())) .orElseGet(() -> new com.mojang.authlib.GameProfile(uuidToUse, "")); try { this.createUser(profile); diff --git a/src/main/java/org/spongepowered/common/world/server/SpongeTicketTypeBuilder.java b/src/main/java/org/spongepowered/common/world/server/SpongeTicketTypeBuilder.java index 9c281ee6f05..5abaf5ecb3b 100644 --- a/src/main/java/org/spongepowered/common/world/server/SpongeTicketTypeBuilder.java +++ b/src/main/java/org/spongepowered/common/world/server/SpongeTicketTypeBuilder.java @@ -77,10 +77,9 @@ public TicketType build() { if (this.comparator == null) { this.comparator = (v1, v2) -> 0; } + // This will load and simulate, but not persist nor keep the dimension active. + final var flag = 1 << 2 & 1 << 4; final var timeout = this.lifetime.isInfinite() ? Constants.ChunkTicket.INFINITE_TIMEOUT : this.lifetime.ticks(); - return (TicketType) (Object) new net.minecraft.server.level.TicketType( - timeout, - false, // TODO - Do we determine if a ticket type should be stored? - net.minecraft.server.level.TicketType.TicketUse.LOADING_AND_SIMULATION); + return (TicketType) (Object) new net.minecraft.server.level.TicketType(timeout,flag); } } 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 91d116ebd68..427e2f20f1e 100644 --- a/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java +++ b/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java @@ -39,16 +39,14 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.TicketType; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.util.Mth; +import net.minecraft.server.level.progress.LevelLoadListener; +import net.minecraft.server.level.progress.LoggingLevelLoadListener; import net.minecraft.util.TimeUtil; import net.minecraft.world.entity.ai.village.VillageSiege; import net.minecraft.world.entity.npc.CatSpawner; import net.minecraft.world.entity.npc.WanderingTraderSpawner; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.CustomSpawner; -import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelSettings; import net.minecraft.world.level.TicketStorage; @@ -87,7 +85,6 @@ import org.spongepowered.api.world.server.storage.ServerWorldProperties; import org.spongepowered.common.SpongeCommon; import org.spongepowered.common.accessor.server.MinecraftServerAccessor; -import org.spongepowered.common.accessor.server.level.ServerLevelAccessor; import org.spongepowered.common.accessor.world.level.storage.PrimaryLevelDataAccessor; import org.spongepowered.common.bridge.core.MappedRegistryBridge; import org.spongepowered.common.bridge.server.level.ServerLevelBridge; @@ -134,6 +131,7 @@ public class SpongeWorldManager implements WorldManager { private final MinecraftServer server; private final Path defaultWorldDirectory, customWorldsDirectory; private final Map, ServerLevel> worlds; + private final LevelLoadListener levelLoadListener; public SpongeWorldManager(final MinecraftServer server) { this.server = server; @@ -145,6 +143,7 @@ public SpongeWorldManager(final MinecraftServer server) { throw new RuntimeException(e); } this.worlds = ((MinecraftServerAccessor) this.server).accessor$levels(); + this.levelLoadListener = LoggingLevelLoadListener.forDedicatedServer(); } @Override @@ -693,12 +692,6 @@ private CompletableFuture unloadWorld0(final ServerLevel level) { PlatformHooks.INSTANCE.getWorldHooks().preUnloadWorld(level); - final int lastSpawnChunkRadius = ((ServerLevelAccessor) level).accessor$lastSpawnChunkRadius(); - if (lastSpawnChunkRadius > 1) { - final BlockPos spawnPoint = level.getSharedSpawnPos(); - level.getChunkSource().removeTicketWithRadius(TicketType.START, new ChunkPos(spawnPoint), lastSpawnChunkRadius); - ((ServerLevelAccessor) level).accessor$setLastSpawnChunkRadius(1); - } final var configAdapter = ((ServerLevelDataBridge) level.getLevelData()).bridge$spongeData().configAdapter(); if (configAdapter != null) { @@ -906,10 +899,9 @@ private ServerLevel createLevel( final long seed = BiomeManager.obfuscateSeed(levelData.worldGenOptions().seed()); final Executor executor = ((MinecraftServerAccessor) this.server).accessor$executor(); - final ChunkProgressListener progressListener = ((MinecraftServerAccessor) this.server).accessor$progressListenerFactory().create(SpongeWorldManager.getSpawnRadius(levelData)); final ServerLevel world = new ServerLevel(this.server, executor, storageSource, levelData, - registryKey, levelStem, progressListener, levelData.isDebugWorld(), seed, spawners, true, null); + registryKey, levelStem, levelData.isDebugWorld(), seed, spawners, true, null); this.worlds.put(registryKey, world); // Ensure that the world border is registered. @@ -939,7 +931,7 @@ private ServerLevel prepareLevel(final ServerLevel level) { final boolean hasSpawnAlready = levelDataBridge.bridge$customSpawnPosition(); if (!hasSpawnAlready) { if (levelDataBridge.bridge$performsSpawnLogic()) { - MinecraftServerAccessor.invoker$setInitialSpawn(level, levelData, worldData.worldGenOptions().generateBonusChest(), isDebugGeneration); + MinecraftServerAccessor.invoker$setInitialSpawn(level, levelData, worldData.worldGenOptions().generateBonusChest(), isDebugGeneration, server.getLevelLoadListener()); } else if (Level.END.equals(level.dimension())) { levelData.setSpawn(ServerLevel.END_SPAWN_POINT, 0); } @@ -985,18 +977,13 @@ private CompletableFuture loadSpawnChunksAsync(final ServerLevel le final ServerChunkCache chunkSource = level.getChunkSource(); level.setDefaultSpawnPos(level.getSharedSpawnPos(), level.getSharedSpawnAngle()); - final int spawnRadius = SpongeWorldManager.getSpawnRadius((ServerLevelData) level.getLevelData()); - final int spawnSize = spawnRadius > 0 ? Mth.square(ChunkProgressListener.calculateDiameter(spawnRadius)) : 0; - final CompletableFuture generationFuture = new CompletableFuture<>(); Sponge.asyncScheduler().submit( Task.builder().plugin(Launch.instance().platformPlugin()).execute(task -> { - if (chunkSource.getTickingGenerated() >= spawnSize) { - Sponge.server().scheduler().submit(Task.builder().plugin(Launch.instance().platformPlugin()).execute(() -> generationFuture.complete(level)).build()); - // Notify the future that we are done - task.cancel(); // And cancel this task - MinecraftServerAccessor.accessor$LOGGER().info("Done preparing start region for dimension {}", level.dimension().location()); - } + Sponge.server().scheduler().submit(Task.builder().plugin(Launch.instance().platformPlugin()).execute(() -> generationFuture.complete(level)).build()); + // Notify the future that we are done + task.cancel(); // And cancel this task + MinecraftServerAccessor.accessor$LOGGER().info("Done preparing start region for dimension {}", level.dimension().location()); }).interval(10, TimeUnit.MILLISECONDS).build() ); @@ -1013,21 +1000,10 @@ private void loadSpawnChunks(final ServerLevel level) { MinecraftServerAccessor.accessor$LOGGER().info("Preparing start region for dimension {}", level.dimension().location()); final BlockPos spawnPoint = level.getSharedSpawnPos(); - final ChunkPos chunkPos = new ChunkPos(spawnPoint); - final ChunkProgressListener progressListener = ((ServerLevelBridge) level).bridge$getChunkProgressListener(); - progressListener.updateSpawnPos(chunkPos); final ServerChunkCache chunkSource = level.getChunkSource(); ((MinecraftServerAccessor) this.server).accessor$nextTickTimeNanos(Util.getNanos()); level.setDefaultSpawnPos(spawnPoint, level.getSharedSpawnAngle()); - final int spawnRadius = SpongeWorldManager.getSpawnRadius((ServerLevelData) level.getLevelData()); - final int spawnSize = spawnRadius > 0 ? Mth.square(ChunkProgressListener.calculateDiameter(spawnRadius)) : 0; - - while (chunkSource.getTickingGenerated() < spawnSize) { - ((MinecraftServerAccessor) this.server).accessor$nextTickTimeNanos(Util.getNanos() + 10L * TimeUtil.NANOSECONDS_PER_MILLISECOND); - ((MinecraftServerAccessor) this.server).accessor$waitUntilNextTick(); - } - ((MinecraftServerAccessor) this.server).accessor$nextTickTimeNanos(Util.getNanos() + 10L * TimeUtil.NANOSECONDS_PER_MILLISECOND); ((MinecraftServerAccessor) this.server).accessor$waitUntilNextTick(); @@ -1035,11 +1011,6 @@ private void loadSpawnChunks(final ServerLevel level) { ((MinecraftServerAccessor) this.server).accessor$nextTickTimeNanos(Util.getNanos() + 10L * TimeUtil.NANOSECONDS_PER_MILLISECOND); ((MinecraftServerAccessor) this.server).accessor$waitUntilNextTick(); - progressListener.stop(); - } - - private static int getSpawnRadius(final ServerLevelData levelData) { - return ((ServerLevelDataBridge) levelData).bridge$performsSpawnLogic() ? levelData.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS) : 0; } private static void updateForcedChunks(final ServerLevel level, final ServerChunkCache serverChunkProvider) { diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/players/GameProfileCacheMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/players/GameProfileCacheMixin_API.java index e6d3552b6ad..c109b5c9ea2 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/players/GameProfileCacheMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/players/GameProfileCacheMixin_API.java @@ -50,7 +50,7 @@ import java.util.function.Predicate; import java.util.stream.Stream; -@Mixin(net.minecraft.server.players.GameProfileCache.class) +@Mixin(net.minecraft.server.players.CachedUserNameToIdResolver.class) public abstract class GameProfileCacheMixin_API implements GameProfileCache { // @formatter:off @@ -95,7 +95,7 @@ public Collection removeIf(final Predicate filter) { final Iterator it = this.profilesByUUID.values().iterator(); while (it.hasNext()) { final GameProfileCache_GameProfileInfoAccessor entry = it.next(); - final GameProfile profile = SpongeGameProfile.of(entry.invoker$getProfile()); + final GameProfile profile = SpongeGameProfile.of(entry.invoker$nameAndId()); final boolean isExpired = entry.invoker$getExpirationDate().getTime() < System.currentTimeMillis(); if (isExpired || filter.test(profile)) { it.remove(); @@ -136,9 +136,9 @@ public Optional findByName(final String name) { @Nullable GameProfileCache_GameProfileInfoAccessor entry = this.profilesByName.get(name.toLowerCase(Locale.ROOT)); if (entry != null && System.currentTimeMillis() >= entry.invoker$getExpirationDate().getTime()) { - final com.mojang.authlib.GameProfile profile = entry.invoker$getProfile(); - this.profilesByUUID.remove(profile.getId()); - this.profilesByName.remove(profile.getName().toLowerCase(Locale.ROOT)); + final var profile = entry.invoker$nameAndId(); + this.profilesByUUID.remove(profile.id()); + this.profilesByName.remove(profile.name().toLowerCase(Locale.ROOT)); entry = null; } @@ -158,7 +158,7 @@ public Map> findByNames(final Iterable nam @Override public Stream stream() { return this.profilesByName.values().stream() - .map(entry -> SpongeGameProfile.of(entry.invoker$getProfile())); + .map(entry -> SpongeGameProfile.of(entry.invoker$nameAndId())); } @Override @@ -172,8 +172,8 @@ public Collection all() { public Stream streamOfMatches(final String name) { final String search = Objects.requireNonNull(name, "name").toLowerCase(Locale.ROOT); return this.profilesByName.values().stream() - .filter(profile -> profile.invoker$getProfile().getName() != null) - .filter(profile -> profile.invoker$getProfile().getName().toLowerCase(Locale.ROOT).startsWith(search)) + .filter(profile -> profile.invoker$nameAndId().name() != null) + .filter(profile -> profile.invoker$nameAndId().name().toLowerCase(Locale.ROOT).startsWith(search)) .map(this::api$updateLastAccess); } @@ -188,6 +188,6 @@ public Collection allMatches(final String name) { return null; } entry.invoker$setLastAccess(this.shadow$getNextOperation()); - return SpongeGameProfile.of(entry.invoker$getProfile()); + return SpongeGameProfile.of(entry.invoker$nameAndId()); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/CopperGolemStatueBlock_PoseMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/CopperGolemStatueBlock_PoseMixin_API.java new file mode 100644 index 00000000000..0ced2233a87 --- /dev/null +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/CopperGolemStatueBlock_PoseMixin_API.java @@ -0,0 +1,33 @@ +/* + * 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.mixin.api.minecraft.world.level.block; + +import net.minecraft.world.level.block.CopperGolemStatueBlock; +import org.spongepowered.api.data.type.CopperGolemPose; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(CopperGolemStatueBlock.Pose.class) +public abstract class CopperGolemStatueBlock_PoseMixin_API implements CopperGolemPose { +} diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/WeatheringCopper_WeatherStateMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/WeatheringCopper_WeatherStateMixin_API.java new file mode 100644 index 00000000000..a01410ae563 --- /dev/null +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/WeatheringCopper_WeatherStateMixin_API.java @@ -0,0 +1,33 @@ +/* + * 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.mixin.api.minecraft.world.level.block; + +import net.minecraft.world.level.block.WeatheringCopper; +import org.spongepowered.api.data.type.CopperOxidation; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(WeatheringCopper.WeatherState.class) +public abstract class WeatheringCopper_WeatherStateMixin_API implements CopperOxidation { +} diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/BlockEntityMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/BlockEntityMixin_API.java index 9c57c3e94b1..75e3f3936b9 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/BlockEntityMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/BlockEntityMixin_API.java @@ -89,7 +89,7 @@ public ServerLocation serverLocation() { throw new RuntimeException("The TileEntity has not been spawned in a world yet!"); } - if (this.level.isClientSide) { + if (this.level.isClientSide()) { throw new RuntimeException("You should not attempt to make a server-side location on the client!"); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/SpawnerBlockEntityMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/SpawnerBlockEntityMixin_API.java index 18c8c25b2c6..ddf98728581 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/SpawnerBlockEntityMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/SpawnerBlockEntityMixin_API.java @@ -51,7 +51,7 @@ public void spawnEntityBatchImmediately(final boolean force) { bridge.bridge$setMaxNearbyEntities(Short.MAX_VALUE); bridge.bridge$setSpawnDelay(0); - if (!this.level.isClientSide) { + if (!this.level.isClientSide()) { this.shadow$getSpawner().serverTick((ServerLevel) this.level, this.worldPosition); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/TrialSpawnerBlockEntityMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/TrialSpawnerBlockEntityMixin_API.java index f8972753682..83e43cc55f2 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/TrialSpawnerBlockEntityMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/block/entity/TrialSpawnerBlockEntityMixin_API.java @@ -40,7 +40,7 @@ public abstract class TrialSpawnerBlockEntityMixin_API extends BlockEntityMixin_ @Override public void spawnImmediately(final boolean force) { - if (this.level.isClientSide) { + if (this.level.isClientSide()) { return; } final var thisLevel = (ServerLevel) this.level; diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/levelgen/NoiseRouterMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/levelgen/NoiseRouterMixin_API.java index c5831f8c3c5..39b4796b568 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/levelgen/NoiseRouterMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/levelgen/NoiseRouterMixin_API.java @@ -44,7 +44,6 @@ public abstract class NoiseRouterMixin_API implements org.spongepowered.api.worl @Shadow @Final private net.minecraft.world.level.levelgen.DensityFunction erosion; @Shadow @Final private net.minecraft.world.level.levelgen.DensityFunction depth; @Shadow @Final private net.minecraft.world.level.levelgen.DensityFunction ridges; - @Shadow @Final private net.minecraft.world.level.levelgen.DensityFunction initialDensityWithoutJaggedness; @Shadow @Final private net.minecraft.world.level.levelgen.DensityFunction finalDensity; @Shadow @Final private net.minecraft.world.level.levelgen.DensityFunction veinToggle; @Shadow @Final private net.minecraft.world.level.levelgen.DensityFunction veinRidged; @@ -101,11 +100,6 @@ public DensityFunction ridges() { return (DensityFunction) this.ridges; } - @Override - public DensityFunction initialDensityWithoutJaggedness() { - return (DensityFunction) this.initialDensityWithoutJaggedness; - } - @Override public DensityFunction finalDensity() { return (DensityFunction) this.finalDensity; diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/adventure/text/format/StyleImplMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/adventure/text/format/StyleImplMixin.java index bb26db49f6d..1ed65fb9aab 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/adventure/text/format/StyleImplMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/adventure/text/format/StyleImplMixin.java @@ -60,7 +60,7 @@ public abstract class StyleImplMixin implements StyleBridge { // insertion $this.insertion(), // font - SpongeAdventure.asVanillaNullable($this.font()) + SpongeAdventure.asVanillaFontDescription($this.font()) ); } // Style is immutable, no need to copy diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/block/BedBlockMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/block/BedBlockMixin.java index 97fee76c145..eecb90a85df 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/block/BedBlockMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/block/BedBlockMixin.java @@ -49,7 +49,7 @@ public class BedBlockMixin { @Inject(method = "useWithoutItem", at = @At(value = "HEAD"), cancellable = true) private void impl$onUseBed(final BlockState param0, final Level param1, final BlockPos param2, final Player param3, final BlockHitResult param5, final CallbackInfoReturnable cir) { - if (!param1.isClientSide) { + if (!param1.isClientSide()) { final Cause currentCause = PhaseTracker.getInstance().currentCause(); final BlockPos bedLocation = param5.getBlockPos(); final BlockSnapshot snapshot = ((ServerWorld) param1).createSnapshot(bedLocation.getX(), bedLocation.getY(), bedLocation.getZ()); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/client/server/IntegratedPlayerListMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/client/server/IntegratedPlayerListMixin.java index 500a95baa45..5e73ff153f7 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/client/server/IntegratedPlayerListMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/client/server/IntegratedPlayerListMixin.java @@ -27,6 +27,7 @@ import com.mojang.authlib.GameProfile; import net.minecraft.client.server.IntegratedPlayerList; import net.minecraft.network.chat.Component; +import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.PlayerList; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -42,11 +43,12 @@ public abstract class IntegratedPlayerListMixin extends PlayerListMixin implements IntegratedPlayerListBridge { // @formatter:off - @Shadow public abstract Component shadow$canPlayerLogin(SocketAddress param0, GameProfile param1); + @Shadow public abstract Component shadow$canPlayerLogin(SocketAddress param0, NameAndId param1); // @formatter:on + @Override public CompletableFuture bridge$canPlayerLoginClient(final SocketAddress param0, final com.mojang.authlib.GameProfile param1) { - final Component component = this.shadow$canPlayerLogin(param0, param1); + final Component component = this.shadow$canPlayerLogin(param0, new NameAndId(param1)); if (component == null) { return this.impl$canPlayerLoginServer(param0, param1); } @@ -54,9 +56,8 @@ public abstract class IntegratedPlayerListMixin extends PlayerListMixin implemen } @Redirect(method = "canPlayerLogin", at = @At(value = "INVOKE", - target = "Lnet/minecraft/server/players/PlayerList;canPlayerLogin(Ljava/net/SocketAddress;Lcom/mojang/authlib/GameProfile;)" - + "Lnet/minecraft/network/chat/Component;")) - private Component impl$redirectCanPlayerLoginSuperCall(final PlayerList playerList, final SocketAddress param0, final GameProfile param1) { + target = "Lnet/minecraft/server/players/PlayerList;canPlayerLogin(Ljava/net/SocketAddress;Lnet/minecraft/server/players/NameAndId;)Lnet/minecraft/network/chat/Component;")) + private Component impl$redirectCanPlayerLoginSuperCall(final PlayerList playerList, final SocketAddress param0, final NameAndId param1) { return null; // we'll handle it above which we'll indicate by returning null. } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/network/syncher/SynchedEntityDataMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/network/syncher/SynchedEntityDataMixin.java index e2175da5295..e135c13840b 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/network/syncher/SynchedEntityDataMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/network/syncher/SynchedEntityDataMixin.java @@ -84,7 +84,7 @@ public abstract class SynchedEntityDataMixin { final var thisEntity = (Entity) this.entity; - if (thisEntity.level() == null || thisEntity.level().isClientSide || ((EntityBridge) this.entity).bridge$isConstructing()) { + if (thisEntity.level() == null || thisEntity.level().isClientSide() || ((EntityBridge) this.entity).bridge$isConstructing()) { return dataentry; } final Optional> converter = ((EntityDataAccessorBridge) (Object) accessor).bridge$getDataConverter(); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java index 296f4f89f7a..c4c1efd11f3 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java @@ -41,12 +41,12 @@ import net.minecraft.server.ServerFunctionManager; import net.minecraft.server.WorldStem; import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.progress.ChunkProgressListener; +import net.minecraft.server.level.progress.LevelLoadListener; import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.SimpleReloadInstance; -import net.minecraft.server.players.GameProfileCache; import net.minecraft.server.players.PlayerList; +import net.minecraft.server.players.UserNameToIdResolver; import net.minecraft.util.Unit; import net.minecraft.util.thread.BlockableEventLoop; import net.minecraft.world.Difficulty; @@ -138,7 +138,7 @@ public abstract class MinecraftServerMixin implements SpongeServer, MinecraftSer @Shadow public abstract PlayerList shadow$getPlayerList(); @Shadow public abstract PackRepository shadow$getPackRepository(); @Shadow public abstract RegistryAccess.Frozen shadow$registryAccess(); - @Shadow public abstract GameProfileCache shadow$getProfileCache(); + @Shadow public abstract UserNameToIdResolver shadow$nameToIdCache(); @Shadow public abstract CompletableFuture shadow$reloadResources(final Collection $$0); @Shadow public abstract WorldData shadow$getWorldData(); @Shadow public abstract boolean shadow$haveTime(); @@ -146,6 +146,7 @@ public abstract class MinecraftServerMixin implements SpongeServer, MinecraftSer @Shadow public abstract ResourceManager shadow$getResourceManager(); // @formatter:on + private final ChatDecorator impl$spongeDecorator = new SpongeChatDecorator(); private @Nullable SpongeServerScopedServiceProvider impl$serviceProvider; protected @Nullable ResourcePackRequest impl$resourcePack; @@ -213,8 +214,12 @@ public Subject subject() { frame.pushCause(Sponge.systemSubject()); } - @Inject(method = "createLevels", at = @At(value = "INVOKE", ordinal = 0, - target = "Lnet/minecraft/server/level/ServerLevel;(Lnet/minecraft/server/MinecraftServer;Ljava/util/concurrent/Executor;Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;Lnet/minecraft/world/level/storage/ServerLevelData;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/dimension/LevelStem;Lnet/minecraft/server/level/progress/ChunkProgressListener;ZJLjava/util/List;ZLnet/minecraft/world/RandomSequences;)V")) + @Inject(method = "createLevels", at = @At(value = "NEW", + target = "(Lnet/minecraft/server/MinecraftServer;Ljava/util/concurrent/Executor;Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;Lnet/minecraft/world/level/storage/ServerLevelData;Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/world/level/dimension/LevelStem;ZJLjava/util/List;ZLnet/minecraft/world/RandomSequences;)Lnet/minecraft/server/level/ServerLevel;" + ), slice = @Slice( + from = @At(value = "INVOKE", target = "Lnet/minecraft/core/Registry;getValue(Lnet/minecraft/resources/ResourceKey;)Ljava/lang/Object;"), + to = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;readScoreboard(Lnet/minecraft/world/level/storage/DimensionDataStorage;)V") + )) private void impl$onCreateDefaultLevel(final CallbackInfo ci, @Local final ServerLevelData levelData, @Local final LevelStem levelStem) { ((PrimaryLevelDataBridge) levelData).bridge$populateFromLevelStem(levelStem); ((ServerLevelDataBridge) levelData).bridge$spongeData().setKey(DefaultWorldKeys.DEFAULT); @@ -234,10 +239,12 @@ public Subject subject() { } @WrapMethod(method = "setInitialSpawn") - private static void impl$wrapSetInitialSpawn(final ServerLevel level, final ServerLevelData levelData, final boolean generateBonusChest, final boolean debugWorld, final Operation original) { + private static void impl$wrapSetInitialSpawn( + final ServerLevel level, final ServerLevelData levelData, final boolean generateBonusChest, + final boolean debugWorld, final LevelLoadListener listener, Operation original) { try (final var state = GenerationPhase.State.TERRAIN_GENERATION.createPhaseContext(PhaseTracker.getInstance())) { state.buildAndSwitch(); - original.call(level, levelData, generateBonusChest, debugWorld); + original.call(level, levelData, generateBonusChest, debugWorld, listener); } } @@ -246,7 +253,7 @@ public Subject subject() { * @reason Multi world. */ @Overwrite - private void prepareLevels(final ChunkProgressListener progressListener) { + private void prepareLevels() { this.worldManager().prepareLevels(); } @@ -262,7 +269,7 @@ public String getServerModName() { @Inject(method = "stopServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;saveAllChunks(ZZZ)Z")) private void impl$callUnloadWorldEvents(final CallbackInfo ci) { - for(final ServerLevel level : this.shadow$getAllLevels()) { + for (final ServerLevel level : this.shadow$getAllLevels()) { final UnloadWorldEvent unloadWorldEvent = SpongeEventFactory.createUnloadWorldEvent(PhaseTracker.getInstance().currentCause(), (ServerWorld) level); SpongeCommon.post(unloadWorldEvent); } @@ -387,7 +394,7 @@ public boolean saveAllChunks(final boolean suppressLog, final boolean flush, fin // Save the usercache.json file every 10 minutes or if forced to if (isForced || this.tickCount % 6000 == 0) { // We want to save the username cache json, as we normally bypass it. - final GameProfileCache profileCache = this.shadow$getProfileCache(); + final var profileCache = this.shadow$nameToIdCache(); ((GameProfileCacheBridge) profileCache).bridge$setCanSave(true); profileCache.save(); ((GameProfileCacheBridge) profileCache).bridge$setCanSave(false); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedPlayerListMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedPlayerListMixin.java index 6a23e98a14a..992760e055e 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedPlayerListMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedPlayerListMixin.java @@ -29,6 +29,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.RegistryLayer; import net.minecraft.server.dedicated.DedicatedPlayerList; +import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.PlayerList; import net.minecraft.world.level.storage.PlayerDataStorage; import org.spongepowered.api.Sponge; @@ -51,13 +52,13 @@ public DedicatedPlayerListMixin(final MinecraftServer server, final LayeredRegis } @Inject(method = "isWhiteListed", at = @At("HEAD"), cancellable = true) - private void impl$checkForWhitelistBypassPermission(final GameProfile profile, final CallbackInfoReturnable ci) { + private void impl$checkForWhitelistBypassPermission(final NameAndId profile, final CallbackInfoReturnable ci) { if (!this.isUsingWhitelist() || this.getWhiteList().isWhiteListed(profile)) { ci.setReturnValue(true); return; } final PermissionService permissionService = Sponge.server().serviceProvider().permissionService(); - Subject subject = permissionService.userSubjects().subject(profile.getId().toString()).orElse(null); + Subject subject = permissionService.userSubjects().subject(profile.id().toString()).orElse(null); if (subject == null) { subject = permissionService.userSubjects().defaults(); } @@ -66,9 +67,9 @@ public DedicatedPlayerListMixin(final MinecraftServer server, final LayeredRegis } @Inject(method = "canBypassPlayerLimit", at = @At("HEAD"), cancellable = true) - private void impl$checkForPlayerLimitBypassPermission(final GameProfile profile, final CallbackInfoReturnable ci) { + private void impl$checkForPlayerLimitBypassPermission(final NameAndId profile, final CallbackInfoReturnable ci) { final PermissionService permissionService = Sponge.server().serviceProvider().permissionService(); - Subject subject = permissionService.userSubjects().subject(profile.getId().toString()).orElse(null); + Subject subject = permissionService.userSubjects().subject(profile.id().toString()).orElse(null); if (subject == null) { subject = permissionService.userSubjects().defaults(); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedServerMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedServerMixin.java index 3539859ecd7..8f29486072b 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedServerMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedServerMixin.java @@ -33,9 +33,8 @@ import net.minecraft.server.WorldStem; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.dedicated.DedicatedServerSettings; -import net.minecraft.server.level.progress.ChunkProgressListenerFactory; import net.minecraft.server.packs.repository.PackRepository; -import net.minecraft.server.players.GameProfileCache; +import net.minecraft.server.players.UserNameToIdResolver; import net.minecraft.world.level.storage.LevelStorageSource; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -55,21 +54,22 @@ public abstract class DedicatedServerMixin extends MinecraftServerMixin { @Inject(method = "", at = @At("TAIL")) - private void impl$setServerOnGame(Thread $$0, LevelStorageSource.LevelStorageAccess $$1, PackRepository $$2, WorldStem $$3, - DedicatedServerSettings $$4, DataFixer $$5, Services $$6, ChunkProgressListenerFactory $$7, CallbackInfo ci) { + private void impl$setServerOnGame( + final Thread $$0, final LevelStorageSource.LevelStorageAccess $$1, final PackRepository $$2, final WorldStem $$3, + final DedicatedServerSettings $$4, final DataFixer $$5, final Services $$6, final CallbackInfo ci + ) { $$4.getProperties().serverResourcePackInfo.ifPresent(packInfo -> { try { this.impl$resourcePack = ResourcePackRequest.resourcePackRequest() - .packs(ResourcePackInfo.resourcePackInfo(packInfo.id(), new URI(packInfo.url()), packInfo.hash())) - .required(packInfo.isRequired()) - .prompt(SpongeAdventure.asAdventure(Optional.ofNullable(packInfo.prompt()))) - .build(); + .packs(ResourcePackInfo.resourcePackInfo(packInfo.id(), new URI(packInfo.url()), packInfo.hash())) + .required(packInfo.isRequired()) + .prompt(SpongeAdventure.asAdventure(Optional.ofNullable(packInfo.prompt()))) + .build(); } catch (final URISyntaxException e) { e.printStackTrace(); } }); SpongeCommon.game().setServer(this); - $$6.profileCache().load(); } @Override @@ -77,8 +77,8 @@ public abstract class DedicatedServerMixin extends MinecraftServerMixin { return this.shadow$isRunning(); } - @WrapOperation(method = "initServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/GameProfileCache;save()V")) - private void onSave(final GameProfileCache cache, final Operation original) { + @WrapOperation(method = "initServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/UserNameToIdResolver;save()V")) + private void onSave(final UserNameToIdResolver cache, final Operation original) { ((GameProfileCacheBridge) cache).bridge$setCanSave(true); original.call(cache); ((GameProfileCacheBridge) cache).bridge$setCanSave(false); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java index 4920948720d..9c7f5dde43b 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java @@ -44,7 +44,6 @@ import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.level.progress.ChunkProgressListener; import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.server.players.PlayerList; import net.minecraft.sounds.SoundEvent; @@ -55,7 +54,6 @@ import net.minecraft.world.entity.ai.village.poi.PoiType; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.CustomSpawner; -import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; import net.minecraft.world.level.ServerExplosion; import net.minecraft.world.level.block.Block; @@ -159,16 +157,16 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerLevel private LevelStorageSource.LevelStorageAccess impl$levelSave; private CustomBossEvents impl$bossBarManager; - private ChunkProgressListener impl$chunkProgressListener; private Weather impl$prevWeather; private boolean impl$isManualSave = false; private long impl$preTickTime = 0L; @Inject(method = "", at = @At("TAIL")) private void impl$onInit( - final MinecraftServer server, final Executor executor, final LevelStorageSource.LevelStorageAccess storage, final ServerLevelData levelData, - final net.minecraft.resources.ResourceKey key, final LevelStem levelStem, final ChunkProgressListener listener, final boolean debug, final long biomeSeed, - final List spawners, final boolean tick, final RandomSequences randomSequences, final CallbackInfo ci + final MinecraftServer server, final Executor executor, final LevelStorageSource.LevelStorageAccess storage, + final ServerLevelData levelData, final net.minecraft.resources.ResourceKey key, final LevelStem levelStem, + final boolean debug, final long biomeSeed, final List spawners, final boolean tick, + final RandomSequences randomSequences, final CallbackInfo ci ) { final SpongeServerLevelData spongeData = ((ServerLevelDataBridge) levelData).bridge$spongeData(); @@ -186,7 +184,6 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerLevel } this.impl$levelSave = storage; - this.impl$chunkProgressListener = listener; this.impl$prevWeather = ((ServerWorld) this).weather(); ((LevelTicksBridge) this.blockTicks).bridge$level((ServerLevel) (Object) this); ((LevelTicksBridge) this.fluidTicks).bridge$level((ServerLevel) (Object) this); @@ -209,11 +206,6 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerLevel return this.impl$levelSave; } - @Override - public ChunkProgressListener bridge$getChunkProgressListener() { - return this.impl$chunkProgressListener; - } - @Override public boolean bridge$isLoaded() { if (((LevelBridge) this).bridge$isFake()) { @@ -355,18 +347,6 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerLevel return server.getWorldData(); } - @Redirect(method = "setDefaultSpawnPos", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/level/GameRules;getInt(Lnet/minecraft/world/level/GameRules$Key;)I" - )) - private int impl$respectKeepSpawnLoaded(GameRules gameRules, GameRules.Key key) { - if ((((ServerLevelDataBridge) this.shadow$getLevelData()).bridge$performsSpawnLogic())) { - return gameRules.getInt(key); - } - return 0; - } - @Inject(method = "save", at = @At("HEAD"), cancellable = true) public void impl$postSaveWorldEventPre(final CallbackInfo ci, final @Share("manualSave") LocalBooleanRef manualSave) { manualSave.set(this.impl$isManualSave); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCacheMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCacheMixin.java index 0d5c70af339..a3708770f1c 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCacheMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCacheMixin.java @@ -24,7 +24,8 @@ */ package org.spongepowered.common.mixin.core.server.players; -import net.minecraft.server.players.GameProfileCache; +import net.minecraft.server.players.CachedUserNameToIdResolver; +import net.minecraft.server.players.NameAndId; import org.spongepowered.api.Sponge; import org.spongepowered.api.profile.GameProfile; import org.spongepowered.asm.mixin.Final; @@ -45,11 +46,11 @@ import java.util.Optional; import java.util.UUID; -@Mixin(GameProfileCache.class) +@Mixin(CachedUserNameToIdResolver.class) public abstract class GameProfileCacheMixin implements GameProfileCacheBridge { // @formatter:off - @Shadow public void shadow$add(final com.mojang.authlib.GameProfile profile) {} + @Shadow public void shadow$add(final NameAndId profile) {} @Shadow @Final private Map profilesByUUID; @Shadow @Final private Map profilesByName; // @formatter:on @@ -65,7 +66,7 @@ public abstract class GameProfileCacheMixin implements GameProfileCacheBridge { if (accessor.invoker$getExpirationDate().getTime() < System.currentTimeMillis()) { this.profilesByUUID.remove(uniqueId, accessor); - this.profilesByName.remove(accessor.invoker$getProfile().getName(), accessor); + this.profilesByName.remove(accessor.invoker$nameAndId().name(), accessor); return Optional.empty(); } @@ -81,7 +82,7 @@ public abstract class GameProfileCacheMixin implements GameProfileCacheBridge { } if (accessor.invoker$getExpirationDate().getTime() < System.currentTimeMillis()) { - this.profilesByUUID.remove(accessor.invoker$getProfile().getId(), accessor); + this.profilesByUUID.remove(accessor.invoker$nameAndId().id(), accessor); this.profilesByName.remove(lowerName, accessor); return Optional.empty(); } @@ -92,17 +93,18 @@ public abstract class GameProfileCacheMixin implements GameProfileCacheBridge { @Override public void bridge$add(final com.mojang.authlib.GameProfile profile, final boolean full, final boolean signed) { GameProfileCache_GameProfileInfoAccessor accessor = this.profilesByUUID.get(Objects.requireNonNull(profile, "profile").getId()); - final com.mojang.authlib.GameProfile current = accessor == null ? null : accessor.invoker$getProfile(); + final NameAndId current = accessor == null ? null : accessor.invoker$nameAndId(); // Don't allow basic game profiles to overwrite the contents if already // an entry exists that is full. - if (current != null && Objects.equals(current.getId(), profile.getId()) && - Objects.equals(current.getName(), profile.getName()) && !full) { + if (current != null && Objects.equals(current.id(), profile.getId()) && + Objects.equals(current.name(), profile.getName()) && !full) { return; } - this.shadow$add(profile); + final var nameAndIDToAdd = new NameAndId(profile); + this.shadow$add(nameAndIDToAdd); accessor = this.profilesByUUID.get(profile.getId()); - if (accessor == null || accessor.invoker$getProfile() != profile) { + if (accessor == null || accessor.invoker$nameAndId() != nameAndIDToAdd) { return; } final GameProfileCache_GameProfileInfoBridge bridge = (GameProfileCache_GameProfileInfoBridge) accessor; @@ -113,18 +115,18 @@ public abstract class GameProfileCacheMixin implements GameProfileCacheBridge { @Override public void bridge$add(final GameProfile profile, final boolean full, final boolean signed) { GameProfileCache_GameProfileInfoAccessor accessor = this.profilesByUUID.get(Objects.requireNonNull(profile, "profile").uniqueId()); - final com.mojang.authlib.GameProfile current = accessor == null ? null : accessor.invoker$getProfile(); - final com.mojang.authlib.GameProfile mcProfile = SpongeGameProfile.toMcProfile(profile); + final var current = accessor == null ? null : accessor.invoker$nameAndId(); + final var mcProfile = SpongeGameProfile.toNameAndId(profile); // Don't allow basic game profiles to overwrite the contents if already // an entry exists that is full. - if (current != null && Objects.equals(current.getId(), mcProfile.getId()) && - Objects.equals(current.getName(), mcProfile.getName()) && !full) { + if (current != null && Objects.equals(current.id(), mcProfile.id()) && + Objects.equals(current.name(), mcProfile.name()) && !full) { return; } this.shadow$add(mcProfile); accessor = this.profilesByUUID.get(profile.uniqueId()); - if (accessor == null || accessor.invoker$getProfile() != mcProfile) { + if (accessor == null || accessor.invoker$nameAndId() != mcProfile) { return; } ((GameProfileCache_GameProfileInfoBridge) accessor).bridge$set(profile, full, signed); @@ -136,9 +138,9 @@ public abstract class GameProfileCacheMixin implements GameProfileCacheBridge { } @Inject(method = "add", at = @At(value = "RETURN")) - private void impl$updateCacheUsername(final com.mojang.authlib.GameProfile profile, final CallbackInfo ci) { - if (profile.getName() != null) { - ((SpongeServer) Sponge.server()).getUsernameCache().setUsername(profile.getId(), profile.getName()); + private void impl$updateCacheUsername(final NameAndId profile, final CallbackInfo ci) { + if (!profile.name().isEmpty()) { + ((SpongeServer) Sponge.server()).getUsernameCache().setUsername(profile.id(), profile.name()); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCache_GameProfileInfoMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCache_GameProfileInfoMixin.java index 5a11c591048..5a29e3c28a7 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCache_GameProfileInfoMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCache_GameProfileInfoMixin.java @@ -24,6 +24,7 @@ */ package org.spongepowered.common.mixin.core.server.players; +import net.minecraft.server.players.NameAndId; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.profile.GameProfile; import org.spongepowered.asm.mixin.Final; @@ -32,10 +33,10 @@ import org.spongepowered.common.bridge.server.players.GameProfileCache_GameProfileInfoBridge; import org.spongepowered.common.profile.SpongeGameProfile; -@Mixin(targets = "net.minecraft.server.players.GameProfileCache$GameProfileInfo") +@Mixin(targets = "net/minecraft/server/players/CachedUserNameToIdResolver$GameProfileInfo") public abstract class GameProfileCache_GameProfileInfoMixin implements GameProfileCache_GameProfileInfoBridge { - @Shadow @Final private com.mojang.authlib.GameProfile profile; + @Shadow @Final private NameAndId nameAndId; private boolean impl$isFull; private boolean impl$isSigned; @@ -75,7 +76,7 @@ public abstract class GameProfileCache_GameProfileInfoMixin implements GameProfi if (basic != null) { return basic; } - basic = this.impl$basic = SpongeGameProfile.basicOf(this.profile); + basic = this.impl$basic = SpongeGameProfile.basicOf(this.nameAndId); return basic; } @@ -92,11 +93,11 @@ public abstract class GameProfileCache_GameProfileInfoMixin implements GameProfi if (!this.impl$isSigned) { return null; } - full = this.impl$fullSigned = SpongeGameProfile.of(this.profile); + full = this.impl$fullSigned = SpongeGameProfile.of(this.nameAndId); } else { final GameProfile fullSigned = this.impl$fullSigned; full = this.impl$fullUnsigned = SpongeGameProfile.unsignedOf( - fullSigned == null ? SpongeGameProfile.of(this.profile) : fullSigned); + fullSigned == null ? SpongeGameProfile.of(this.nameAndId) : fullSigned); } return full; } 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 34d28462f2f..510944e8884 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 @@ -316,7 +316,7 @@ public abstract class EntityMixin implements EntityBridge, PlatformEntityBridge, @Override public boolean bridge$dismountRidingEntity(final DismountType type) { - if (!this.shadow$level().isClientSide && ShouldFire.RIDE_ENTITY_EVENT_DISMOUNT) { + if (!this.shadow$level().isClientSide() && ShouldFire.RIDE_ENTITY_EVENT_DISMOUNT) { try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) { frame.pushCause(this); frame.addContext(EventContextKeys.DISMOUNT_TYPE, type); @@ -532,7 +532,7 @@ public Entity teleport(final TeleportTransition transition) { } for (Entity recreatedPassenger : recreatedPassengers) { - recreatedPassenger.startRiding(newEntity, true); + recreatedPassenger.startRiding(newEntity, true, true); } oldLevel.resetEmptyTime(); @@ -608,7 +608,7 @@ public Entity teleport(final TeleportTransition transition) { return event.destinationPosition(); } - @Inject(method = "startRiding(Lnet/minecraft/world/entity/Entity;Z)Z", + @Inject(method = "startRiding(Lnet/minecraft/world/entity/Entity;ZZ)Z", at = @At( value = "FIELD", target = "Lnet/minecraft/world/entity/Entity;vehicle:Lnet/minecraft/world/entity/Entity;", @@ -616,9 +616,9 @@ public Entity teleport(final TeleportTransition transition) { ), cancellable = true ) - private void impl$onStartRiding(final Entity vehicle, final boolean force, + private void impl$onStartRiding(final Entity vehicle, final boolean force, final boolean createPortal, final CallbackInfoReturnable ci) { - if (!this.shadow$level().isClientSide && ShouldFire.RIDE_ENTITY_EVENT_MOUNT) { + if (!this.shadow$level().isClientSide() && ShouldFire.RIDE_ENTITY_EVENT_MOUNT) { PhaseTracker.getInstance().pushCause(this); if (SpongeCommon.post(SpongeEventFactory.createRideEntityEventMount(PhaseTracker.getInstance().currentCause(), (org.spongepowered.api.entity.Entity) vehicle))) { ci.cancel(); @@ -707,7 +707,7 @@ public void stopRiding() { at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/Block;fallOn(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/Entity;D)V")) private void impl$onFallOnCollide(final Block block, final Level world, final BlockState state, final BlockPos pos, final Entity entity, final double fallDistance) { - if (!ShouldFire.COLLIDE_BLOCK_EVENT_FALL || world.isClientSide) { + if (!ShouldFire.COLLIDE_BLOCK_EVENT_FALL || world.isClientSide()) { block.fallOn(world, state, pos, entity, fallDistance); return; } @@ -727,7 +727,7 @@ public void stopRiding() { ) private void impl$onStepOnCollide(final Block block, final Level world, final BlockPos pos, final BlockState state, final Entity entity, Operation original) { - if (!ShouldFire.COLLIDE_BLOCK_EVENT_STEP_ON || world.isClientSide) { + if (!ShouldFire.COLLIDE_BLOCK_EVENT_STEP_ON || world.isClientSide()) { original.call(block, world, pos, state, entity); return; } @@ -748,7 +748,7 @@ public void stopRiding() { private void impl$onCheckInsideBlocksCollide( final BlockState blockState, final Level worldIn, final BlockPos pos, final Entity entityIn, final InsideBlockEffectApplier insideBlockEffectApplier, final Operation original) { - if (!ShouldFire.COLLIDE_BLOCK_EVENT_INSIDE || worldIn.isClientSide || blockState.isAir()) { + if (!ShouldFire.COLLIDE_BLOCK_EVENT_INSIDE || worldIn.isClientSide() || blockState.isAir()) { original.call(blockState, worldIn, pos, entityIn, insideBlockEffectApplier); return; } @@ -1000,7 +1000,7 @@ public void stopRiding() { }*/ - @Redirect(method = "startRiding(Lnet/minecraft/world/entity/Entity;Z)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EntityType;canSerialize()Z")) + @Redirect(method = "startRiding(Lnet/minecraft/world/entity/Entity;ZZ)Z", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/EntityType;canSerialize()Z")) private boolean impl$allowRidingAnything(final EntityType instance) { //Vanilla has started to prevent riding non-serializable entities. //This results in players being unable to ride other players. diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/LeashableMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/LeashableMixin.java index 7388491b26c..c4ca8d3f104 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/LeashableMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/LeashableMixin.java @@ -45,7 +45,7 @@ public interface LeashableMixin { @Inject(method = "setLeashedTo(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/entity/Entity;Z)V", at = @At("HEAD"), cancellable = true) private static void impl$onSetLeashedTo(final E $$0, final net.minecraft.world.entity.Entity $$1, final boolean $$2, final CallbackInfo ci) { - if (!$$0.level().isClientSide) { + if (!$$0.level().isClientSide()) { final Cause currentCause = PhaseTracker.getInstance().currentCause(); if (Sponge.eventManager().post(SpongeEventFactory.createLeashEntityEvent(currentCause, (Entity) $$0))) { ci.cancel(); @@ -55,7 +55,7 @@ public interface LeashableMixin { @Inject(method = "dropLeash(Lnet/minecraft/world/entity/Entity;ZZ)V", at = @At("HEAD"), cancellable = true) private static void impl$onDropLeash(final net.minecraft.world.entity.Entity entity, final boolean $$1, final boolean $$2, final CallbackInfo ci) { - if (entity == null || entity.level().isClientSide) { + if (entity == null || entity.level().isClientSide()) { return; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/LightningBoltMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/LightningBoltMixin.java index 75cf1bfe0c2..7a781f50997 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/LightningBoltMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/LightningBoltMixin.java @@ -65,7 +65,7 @@ public abstract class LightningBoltMixin extends EntityMixin { private List impl$ThrowEventAndProcess( final Level level, final Entity thisEntity, final AABB boundingBox, final Predicate predicate ) { - if (this.shadow$isRemoved() || this.shadow$level().isClientSide) { + if (this.shadow$isRemoved() || this.shadow$level().isClientSide()) { return Collections.emptyList(); } final List originalEntities = level.getEntities(thisEntity, boundingBox, predicate); @@ -87,7 +87,7 @@ public abstract class LightningBoltMixin extends EntityMixin { ) ) private void impl$ThrowEventAndProcess(final CallbackInfo ci) { - if (this.shadow$isRemoved() || this.shadow$level().isClientSide || this.life >= 0) { + if (this.shadow$isRemoved() || this.shadow$level().isClientSide() || this.life >= 0) { return; } try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) { diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/LivingEntityMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/LivingEntityMixin.java index 9df4af654ab..75b665d9049 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/LivingEntityMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/LivingEntityMixin.java @@ -278,7 +278,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/LivingEntity;useItem:Lnet/minecraft/world/item/ItemStack;")) private void impl$onSetActiveItemStack(final InteractionHand hand, final CallbackInfo ci, final ItemStack stack) { - if (this.shadow$level().isClientSide) { + if (this.shadow$level().isClientSide()) { return; } @@ -303,7 +303,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt at = @At(value = "FIELD", target = "Lnet/minecraft/world/entity/LivingEntity;useItemRemaining:I")) private void impl$getItemDuration(final LivingEntity this$0, final int count) { - if (this.shadow$level().isClientSide) { + if (this.shadow$level().isClientSide()) { this.useItemRemaining = count; } // If we're on the server, do nothing, since we already set this field on onSetActiveItemStack @@ -332,7 +332,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt target = "Lnet/minecraft/world/entity/LivingEntity;getUseItemRemainingTicks()I", ordinal = 0)) private int impl$onGetRemainingItemDuration(final LivingEntity self) { - if (this.shadow$level().isClientSide) { + if (this.shadow$level().isClientSide()) { return self.getUseItemRemainingTicks(); } @@ -375,7 +375,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt 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 void impl$onUpdateItemUse(final CallbackInfo ci) { - if (this.shadow$level().isClientSide) { + if (this.shadow$level().isClientSide()) { return; } @@ -405,7 +405,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;setItemInHand(Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/item/ItemStack;)V")) private void impl$onSetHeldItem(final LivingEntity self, final InteractionHand hand, final ItemStack stack) { - if (this.shadow$level().isClientSide) { + if (this.shadow$level().isClientSide()) { self.setItemInHand(hand, stack); return; } @@ -450,7 +450,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt target = "Lnet/minecraft/world/item/ItemStack;releaseUsing(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/LivingEntity;I)V")) // stopActiveHand private void impl$onStopPlayerUsing(final ItemStack stack, final net.minecraft.world.level.Level world, final LivingEntity self, final int duration) { - if (this.shadow$level().isClientSide) { + if (this.shadow$level().isClientSide()) { stack.releaseUsing(world, self, duration); return; } @@ -475,7 +475,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt @Inject(method = "stopUsingItem", at = @At("HEAD")) private void impl$onResetActiveHand(final CallbackInfo ci) { - if (this.shadow$level().isClientSide) { + if (this.shadow$level().isClientSide()) { return; } @@ -514,7 +514,7 @@ public abstract class LivingEntityMixin extends EntityMixin implements LivingEnt @Inject(method = "stopSleeping", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;clearSleepingPos()V")) private void impl$callFinishSleepingEvent(final CallbackInfo ci) { - if (this.shadow$level().isClientSide) { + if (this.shadow$level().isClientSide()) { return; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/MobMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/MobMixin.java index 5f98ec106a0..2b8db878368 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/MobMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/MobMixin.java @@ -89,7 +89,7 @@ public abstract class MobMixin extends LivingEntityMixin { */ @Inject(method = "setTarget", at = @At("HEAD"), cancellable = true) private void onSetAttackTarget(@Nullable final LivingEntity entitylivingbaseIn, final CallbackInfo ci) { - if (this.shadow$level().isClientSide || entitylivingbaseIn == null) { + if (this.shadow$level().isClientSide() || entitylivingbaseIn == null) { return; } //noinspection ConstantConditions diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/item/ItemEntityMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/item/ItemEntityMixin.java index 2d138fd14f1..a9c266be068 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/item/ItemEntityMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/item/ItemEntityMixin.java @@ -70,7 +70,7 @@ public abstract class ItemEntityMixin extends EntityMixin implements ItemEntityB @ModifyConstant(method = "mergeWithNeighbours", constant = @Constant(doubleValue = Constants.Entity.Item.DEFAULT_ITEM_MERGE_RADIUS)) private double impl$changeSearchRadiusFromConfig(final double originalRadius) { - if (this.shadow$level().isClientSide || ((LevelBridge) this.shadow$level()).bridge$isFake()) { + if (this.shadow$level().isClientSide() || ((LevelBridge) this.shadow$level()).bridge$isFake()) { return originalRadius; } if (this.impl$cachedRadius == -1) { diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/item/PrimedTntMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/item/PrimedTntMixin.java index 2850c4ee546..d8e8c9a6646 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/item/PrimedTntMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/item/PrimedTntMixin.java @@ -104,7 +104,7 @@ public abstract class PrimedTntMixin extends EntityMixin implements PrimedTntBri @Inject(method = "tick()V", at = @At("RETURN")) private void impl$updateTNTPushPrime(final CallbackInfo ci) { - if (!this.impl$postPrimeTriggered && !this.shadow$level().isClientSide) { + if (!this.impl$postPrimeTriggered && !this.shadow$level().isClientSide()) { this.impl$postPrimeTriggered = true; try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) { if (this.impl$detonator != null) { diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/monster/CreeperMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/monster/CreeperMixin.java index 3eacbbbc617..8c28d0a71bc 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/monster/CreeperMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/monster/CreeperMixin.java @@ -101,7 +101,7 @@ public abstract class CreeperMixin extends MonsterMixin implements FusedExplosiv @Inject(method = "setSwellDir", at = @At("HEAD"), cancellable = true) private void impl$preStateChange(final int state, final CallbackInfo ci) { - if (this.shadow$level().isClientSide) { + if (this.shadow$level().isClientSide()) { return; } @@ -118,7 +118,7 @@ public abstract class CreeperMixin extends MonsterMixin implements FusedExplosiv @Inject(method = "setSwellDir", at = @At("RETURN")) private void impl$postStateChange(final int state, final CallbackInfo ci) { - if (this.shadow$level().isClientSide) { + if (this.shadow$level().isClientSide()) { return; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/AbstractArrowMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/AbstractArrowMixin.java index 7dde827bfc2..54790720d92 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/AbstractArrowMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/AbstractArrowMixin.java @@ -135,7 +135,7 @@ private void onProjectileHit(final EntityHitResult hitResult, final CallbackInfo this.shadow$setYRot(this.shadow$getYRot() + 180.0F); this.yRotO += 180.0F; this.life = 0; - if (!this.shadow$level().isClientSide && this.shadow$getDeltaMovement().lengthSqr() < 1.0E-7D) { + if (!this.shadow$level().isClientSide() && this.shadow$getDeltaMovement().lengthSqr() < 1.0E-7D) { if (this.pickup == AbstractArrow.Pickup.ALLOWED) { this.shadow$spawnAtLocation((ServerLevel) this.shadow$level(), this.shadow$getPickupItem(), 0.1F); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/FireworkRocketEntityMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/FireworkRocketEntityMixin.java index 0eaf48bde87..b88791d9f7d 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/FireworkRocketEntityMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/FireworkRocketEntityMixin.java @@ -120,7 +120,7 @@ public abstract class FireworkRocketEntityMixin extends ProjectileMixin implemen @Inject(method = "tick()V", at = @At("RETURN")) private void impl$postPrimeEvent(final CallbackInfo ci) { - if (this.life == 1 && !this.shadow$level().isClientSide) { + if (this.life == 1 && !this.shadow$level().isClientSide()) { try (final CauseStackManager.StackFrame frame = PhaseTracker.getInstance().pushCauseFrame()) { frame.pushCause(this); frame.addContext(EventContextKeys.PROJECTILE_SOURCE, this.impl$getProjectileSource()); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/FishingHookMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/FishingHookMixin.java index 7972a3ada30..590ab40690a 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/FishingHookMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/FishingHookMixin.java @@ -94,7 +94,7 @@ private void onSetHookedEntity(final net.minecraft.world.entity.@Nullable Entity public int retrieve(final ItemStack stack) { final Player playerEntity = this.shadow$getPlayerOwner(); - if (!this.shadow$level().isClientSide && playerEntity != null) { + if (!this.shadow$level().isClientSide() && playerEntity != null) { int i = 0; // Sponge start diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/ProjectileUtilMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/ProjectileUtilMixin.java index 19c5a4d75cb..de5d48ad2d2 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/ProjectileUtilMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/projectile/ProjectileUtilMixin.java @@ -81,7 +81,7 @@ public abstract class ProjectileUtilMixin { "getEntityHitResult(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/projectile/Projectile;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/AABB;Ljava/util/function/Predicate;)Lnet/minecraft/world/phys/EntityHitResult;" }, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/projectile/ProjectileUtil;getEntityHitResult(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/phys/AABB;Ljava/util/function/Predicate;F)Lnet/minecraft/world/phys/EntityHitResult;")) private static EntityHitResult impl$onGetEntityHitResult(final Level $$0, final Entity $$1, final Vec3 $$2, final Vec3 $$3, final AABB $$4, final Predicate $$5, final float $$6) { - if ($$0.isClientSide) { + if ($$0.isClientSide()) { return ProjectileUtil.getEntityHitResult($$0, $$1, $$2, $$3, $$4, $$5, $$6); } try (final PhaseContext<@NonNull ?> context = EntityPhase.State.COLLISION diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/item/FishingRodItemMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/item/FishingRodItemMixin.java index 591098e940a..bde45e85057 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/item/FishingRodItemMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/item/FishingRodItemMixin.java @@ -71,7 +71,7 @@ private void cancelHookRetraction(Level world, Player player, InteractionHand ha ), cancellable = true) private void onThrowEvent(Level level, Player player, InteractionHand hand, CallbackInfoReturnable cir) { - if (level.isClientSide) { + if (level.isClientSide()) { // Only fire event on server-side to avoid crash on client return; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/item/ItemStackMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/item/ItemStackMixin.java index 25230b4edb6..8a3eac09178 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/item/ItemStackMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/item/ItemStackMixin.java @@ -57,12 +57,11 @@ public abstract class ItemStackMixin implements SpongeDataHolderBridge, DataComp // @formatter:off @Shadow public abstract boolean shadow$isEmpty(); - @Shadow @Final private PatchedDataComponentMap components; + @Shadow @Final PatchedDataComponentMap components; // @formatter:on - @Override public Optional bridge$get(final Key<@NonNull ? extends Value> key) { if (this.shadow$isEmpty()) { @@ -87,12 +86,11 @@ public abstract class ItemStackMixin implements SpongeDataHolderBridge, DataComp return DataHolderProcessor.bridge$remove(this, key); } - @SuppressWarnings("deprecation") @Override public CompoundTag data$getCompound() { final @Nullable CustomData customData = this.components.get(DataComponents.CUSTOM_DATA); if (customData != null && customData != CustomData.EMPTY) { - return customData.getUnsafe(); + return ((CustomDataAccessor) (Object) customData).accessor$tag(); } return null; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/CampfireBlockMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/CampfireBlockMixin.java index fec121c03e4..4db918c5136 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/CampfireBlockMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/CampfireBlockMixin.java @@ -47,7 +47,7 @@ public abstract class CampfireBlockMixin extends BlockMixin { at = @At(value = "INVOKE", target = "Lnet/minecraft/world/damagesource/DamageSources;campfire()Lnet/minecraft/world/damagesource/DamageSource;")) private DamageSource impl$spongeRedirectForFireDamage(final DamageSources instance, final BlockState blockState, final Level world, final BlockPos blockPos, final Entity entity) { final DamageSource source = instance.inFire(); - if (world.isClientSide) { // Short Circuit + if (world.isClientSide()) { // Short Circuit return source; } final ServerLocation location = ServerLocation.of((ServerWorld) world, blockPos.getX(), blockPos.getY(), blockPos.getZ()); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/MagmaBlockMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/MagmaBlockMixin.java index ceafbdb938e..5b496394ec9 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/MagmaBlockMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/MagmaBlockMixin.java @@ -48,7 +48,7 @@ public abstract class MagmaBlockMixin extends BlockMixin { final BlockState blockState, final Entity entity ) { final DamageSource source = instance.hotFloor(); - if (world.isClientSide) { // Short Circuit + if (world.isClientSide()) { // Short Circuit return source; } return SpongeDamageSources.createBlockBasedDamageSource((ServerWorld) world, blockPos, source); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/PointedDripstoneBlockMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/PointedDripstoneBlockMixin.java index 8a14da2e824..2edc3d52117 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/PointedDripstoneBlockMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/PointedDripstoneBlockMixin.java @@ -48,7 +48,7 @@ public abstract class PointedDripstoneBlockMixin extends BlockMixin { final BlockPos pos,final Entity ignored, final double distance ) { final DamageSource source = instance.stalagmite(); - if (level.isClientSide) { // Short Circuit + if (level.isClientSide()) { // Short Circuit return source; } return SpongeDamageSources.createBlockBasedDamageSource((ServerWorld) level, pos, source); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/SweetBerryBushBlockMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/SweetBerryBushBlockMixin.java index fd54083550a..d528e0f3a79 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/SweetBerryBushBlockMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/SweetBerryBushBlockMixin.java @@ -48,7 +48,7 @@ public abstract class SweetBerryBushBlockMixin extends BlockMixin { final Level level, final BlockPos pos, final Entity ignored ) { final DamageSource source = instance.sweetBerryBush(); - if (level.isClientSide) { // Short Circuit + if (level.isClientSide()) { // Short Circuit return source; } return SpongeDamageSources.createBlockBasedDamageSource((ServerWorld) level, pos, source); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/BannerBlockEntityMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/BannerBlockEntityMixin.java index 62bfbedae59..f257a850df7 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/BannerBlockEntityMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/BannerBlockEntityMixin.java @@ -50,7 +50,7 @@ public abstract class BannerBlockEntityMixin extends BlockEntityMixin implements @Unique private void impl$markDirtyAndUpdate() { this.shadow$setChanged(); - if (this.level != null && !this.level.isClientSide) { + if (this.level != null && !this.level.isClientSide()) { ((ServerLevel) this.level).getChunkSource().blockChanged(this.shadow$getBlockPos()); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/storage/PlayerDataStorageMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/storage/PlayerDataStorageMixin.java index a44d4984345..b5be3ddb4a3 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/storage/PlayerDataStorageMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/storage/PlayerDataStorageMixin.java @@ -24,9 +24,13 @@ */ package org.spongepowered.common.mixin.core.world.level.storage; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.mojang.datafixers.DataFixer; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.datafix.DataFixTypes; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.storage.PlayerDataStorage; -import net.minecraft.world.level.storage.ValueInput; import org.spongepowered.api.data.Keys; import org.spongepowered.api.entity.living.player.server.ServerPlayer; import org.spongepowered.asm.mixin.Final; @@ -34,7 +38,6 @@ 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 org.spongepowered.common.SpongeCommon; import org.spongepowered.common.SpongeServer; diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/ticks/SavedTickMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/ticks/SavedTickMixin.java index e3e0edad8a5..32a8c386887 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/ticks/SavedTickMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/ticks/SavedTickMixin.java @@ -40,6 +40,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.common.accessor.world.item.component.CustomDataAccessor; import org.spongepowered.common.bridge.CreatorTrackedBridge; import org.spongepowered.common.bridge.data.DataCompoundHolder; import org.spongepowered.common.data.DataUtil; @@ -90,7 +91,7 @@ public abstract class SavedTickMixin implements SpongeMutableDataHolder, Data .apply(instance, (t, blockPos, integer, tickPriority, customData) -> { final var tick = function.apply(t, blockPos, integer, tickPriority); customData.ifPresent(data -> { - ((DataCompoundHolder) (Object) tick).data$setCompound(data.getUnsafe()); + ((DataCompoundHolder) (Object) tick).data$setCompound(((CustomDataAccessor) (Object) data).accessor$tag()); DataUtil.syncTagToData(tick); ((DataCompoundHolder) (Object) tick).data$setCompound(null); }); diff --git a/src/mixins/java/org/spongepowered/common/mixin/inventory/event/world/inventory/AbstractContainerMenuMixin_Inventory.java b/src/mixins/java/org/spongepowered/common/mixin/inventory/event/world/inventory/AbstractContainerMenuMixin_Inventory.java index 4f9cbd0a420..22a981b0e10 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/inventory/event/world/inventory/AbstractContainerMenuMixin_Inventory.java +++ b/src/mixins/java/org/spongepowered/common/mixin/inventory/event/world/inventory/AbstractContainerMenuMixin_Inventory.java @@ -191,7 +191,7 @@ public abstract class AbstractContainerMenuMixin_Inventory implements TrackedCon private ItemStack impl$transferStackInSlot(final AbstractContainerMenu thisContainer, final Player player, final int slotId) { final ItemStack result = thisContainer.quickMoveStack(player, slotId); // Crafting on Serverside? - if (((LevelBridge) player.level()).bridge$isFake() || player.level().isClientSide || !(thisContainer.getSlot(slotId) instanceof ResultSlot)) { + if (((LevelBridge) player.level()).bridge$isFake() || player.level().isClientSide() || !(thisContainer.getSlot(slotId) instanceof ResultSlot)) { return result; } this.bridge$detectAndSendChanges(true, true); diff --git a/src/mixins/java/org/spongepowered/common/mixin/tracker/world/entity/LivingEntityMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/world/entity/LivingEntityMixin_Tracker.java index c8b3c0fdd52..4531442bff5 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/tracker/world/entity/LivingEntityMixin_Tracker.java +++ b/src/mixins/java/org/spongepowered/common/mixin/tracker/world/entity/LivingEntityMixin_Tracker.java @@ -180,7 +180,7 @@ public abstract class LivingEntityMixin_Tracker extends EntityMixin_Tracker { at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;pushEntities()V") ) private void tracker$switchIntoCollisions(final LivingEntity livingEntity) { - if (this.shadow$level().isClientSide) { + if (this.shadow$level().isClientSide()) { this.shadow$pushEntities(); return; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/tracker/world/level/chunk/storage/SerializableChunkDataMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/world/level/chunk/storage/SerializableChunkDataMixin_Tracker.java index dad3af2cb99..4d001901e9a 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/tracker/world/level/chunk/storage/SerializableChunkDataMixin_Tracker.java +++ b/src/mixins/java/org/spongepowered/common/mixin/tracker/world/level/chunk/storage/SerializableChunkDataMixin_Tracker.java @@ -55,6 +55,7 @@ public abstract class SerializableChunkDataMixin_Tracker implements Serializable } } + @SuppressWarnings("deprecation") @Override public void bridge$writeTrackerData(final CompoundTag level) { if (this.tracker$intPlayerPos == null && this.tracker$shortPlayerPos == null) { @@ -83,6 +84,7 @@ public abstract class SerializableChunkDataMixin_Tracker implements Serializable } } + @SuppressWarnings("deprecation") @Override public void bridge$parseTrackerData(final CompoundTag fullTag) { final Optional spongeData = fullTag.getCompound(Constants.Sponge.Data.V2.SPONGE_DATA); diff --git a/src/mixins/resources/mixins.sponge.api.json b/src/mixins/resources/mixins.sponge.api.json index f6688cf61c0..9cccab1d8b4 100644 --- a/src/mixins/resources/mixins.sponge.api.json +++ b/src/mixins/resources/mixins.sponge.api.json @@ -379,6 +379,8 @@ "minecraft.world.level.block.MirrorMixin_API", "minecraft.world.level.block.PortalMixin_API", "minecraft.world.level.block.RotationMixin_API", + "minecraft.world.level.block.CopperGolemStatueBlock_PoseMixin_API", + "minecraft.world.level.block.WeatheringCopper_WeatherStateMixin_API", "minecraft.world.level.block.entity.AbstractFurnaceBlockEntityMixin_API", "minecraft.world.level.block.entity.BannerBlockEntityMixin_API", "minecraft.world.level.block.entity.BannerPatternLayers_LayerMixin_API", diff --git a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/MetadataPanel.java b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/MetadataPanel.java index 73e36cc4d27..9bd67bf24d0 100644 --- a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/MetadataPanel.java +++ b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/MetadataPanel.java @@ -276,7 +276,7 @@ protected void drawPanel(final GuiGraphics stack, final int entryRight, int rela } @Override - public boolean mouseClicked(final double mouseX, final double mouseY, final int button) { + public boolean mouseClicked(final double mouseX, final double mouseY, final int button, final boolean repeated) { // Find an entry match for where we clicked final Entry entry = this.getAllEntries().stream() @@ -292,7 +292,7 @@ public boolean mouseClicked(final double mouseX, final double mouseY, final int this.screen.handleComponentClicked(component.getStyle()); return true; } - return super.mouseClicked(mouseX, mouseY, button); + return super.mouseClicked(mouseX, mouseY, button, repeated); } @Override diff --git a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/ScrollPanel.java b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/ScrollPanel.java index 7fa79ba1be8..4e32fa9c1bf 100644 --- a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/ScrollPanel.java +++ b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/ScrollPanel.java @@ -122,8 +122,8 @@ public boolean isMouseOver(final double mouseX, final double mouseY) { } @Override - public boolean mouseClicked(final double mouseX, final double mouseY, final int button) { - if (super.mouseClicked(mouseX, mouseY, button)) { + public boolean mouseClicked(final double mouseX, final double mouseY, final int button, final boolean repeated) { + if (super.mouseClicked(mouseX, mouseY, button, repeated)) { return true; } diff --git a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/FilterableList.java b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/FilterableList.java index 7ebcc9ef51e..313026a015f 100644 --- a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/FilterableList.java +++ b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/FilterableList.java @@ -132,21 +132,21 @@ public void setSelected(@Nullable final E entry) { } @Override - public boolean mouseClicked(final double p_mouseClicked_1_, final double p_mouseClicked_3_, final int p_mouseClicked_5_) { - this.updateScrolling(p_mouseClicked_1_, p_mouseClicked_3_, p_mouseClicked_5_); - if (!this.isMouseOver(p_mouseClicked_1_, p_mouseClicked_3_)) { + public boolean mouseClicked(final double mouseX, final double mouseY, final int button, final boolean repeatedClick) { + this.updateScrolling(mouseX, mouseY, button); + if (!this.isMouseOver(mouseX, mouseY)) { return false; } else { - final E e = this.getEntryAtPosition(p_mouseClicked_1_, p_mouseClicked_3_); + final E e = this.getEntryAtPosition(mouseX, mouseY); if (e != null) { - if (e.mouseClicked(p_mouseClicked_1_, p_mouseClicked_3_, p_mouseClicked_5_)) { + if (e.mouseClicked(mouseX, mouseY, button, repeatedClick)) { this.setFocused(e); this.setDragging(true); return true; } - } else if (p_mouseClicked_5_ == 0) { - this.onClick((int) (p_mouseClicked_1_ - (double) (this.getX() + this.width / 2 - this.getRowWidth() / 2)), - (int) (p_mouseClicked_3_ - (double) this.getY()) + (int) this.scrollAmount() - 4); + } else if (button == 0) { + this.onClick((int) (mouseX - (double) (this.getX() + this.width / 2 - this.getRowWidth() / 2)), + (int) (mouseY - (double) this.getY()) + (int) this.scrollAmount() - 4, repeatedClick); return true; } diff --git a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/PluginSelectionList.java b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/PluginSelectionList.java index 8790eb4acd5..e1bb2371155 100644 --- a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/PluginSelectionList.java +++ b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/PluginSelectionList.java @@ -66,7 +66,7 @@ public void render(final GuiGraphics stack, final int p_render_1_, final int ren } @Override - public boolean mouseClicked(final double p_mouseClicked_1_, final double p_mouseClicked_3_, final int p_mouseClicked_5_) { + public boolean mouseClicked(final double p_mouseClicked_1_, final double p_mouseClicked_3_, final int p_mouseClicked_5_, final boolean repeated) { this.getParentList().setSelected(this); return true; } diff --git a/vanilla/src/main/java/org/spongepowered/vanilla/server/packs/PluginPackResources.java b/vanilla/src/main/java/org/spongepowered/vanilla/server/packs/PluginPackResources.java index 8879fce54c7..88c8c8ffe37 100644 --- a/vanilla/src/main/java/org/spongepowered/vanilla/server/packs/PluginPackResources.java +++ b/vanilla/src/main/java/org/spongepowered/vanilla/server/packs/PluginPackResources.java @@ -31,8 +31,10 @@ import net.minecraft.server.packs.PackLocationInfo; import net.minecraft.server.packs.PackType; import net.minecraft.server.packs.metadata.MetadataSectionType; +import net.minecraft.server.packs.metadata.pack.PackFormat; import net.minecraft.server.packs.metadata.pack.PackMetadataSection; import net.minecraft.server.packs.resources.IoSupplier; +import net.minecraft.util.InclusiveRange; import org.checkerframework.checker.nullness.qual.Nullable; import org.slf4j.Logger; import org.spongepowered.common.SpongeCommon; @@ -43,7 +45,11 @@ import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; -import java.util.*; +import java.util.Collections; +import java.util.Locale; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -57,7 +63,7 @@ public final class PluginPackResources extends AbstractPackResources { public PluginPackResources(final PackLocationInfo info, final PluginContainer container, final @Nullable Path pluginRoot) { super(info); this.container = container; - this.metadata = new PackMetadataSection(Component.literal("Plugin Resources"), 6, Optional.empty()); + this.metadata = new PackMetadataSection(Component.literal("Plugin Resources"), new InclusiveRange<>(PackFormat.of(6))); this.pluginRoot = pluginRoot; } diff --git a/vanilla/src/mixins/java/org/spongepowered/vanilla/mixin/core/server/MinecraftServerMixin_Vanilla.java b/vanilla/src/mixins/java/org/spongepowered/vanilla/mixin/core/server/MinecraftServerMixin_Vanilla.java index 8215f95222a..b1f8e74e1f3 100644 --- a/vanilla/src/mixins/java/org/spongepowered/vanilla/mixin/core/server/MinecraftServerMixin_Vanilla.java +++ b/vanilla/src/mixins/java/org/spongepowered/vanilla/mixin/core/server/MinecraftServerMixin_Vanilla.java @@ -59,13 +59,13 @@ public String getServerModName() { Launch.instance().lifecycle().callStoppingEngineEvent(this); } - @ModifyExpressionValue(method = "lambda$reloadResources$28", at = @At(value = "NEW", target = "Lnet/minecraft/server/packs/resources/MultiPackResourceManager;")) + @ModifyExpressionValue(method = "lambda$reloadResources$29", at = @At(value = "NEW", target = "Lnet/minecraft/server/packs/resources/MultiPackResourceManager;")) private MultiPackResourceManager impl$onReloadResources(final MultiPackResourceManager original) { ((MinecraftServerBridge) this).bridge$reloadServerRegistries((RegistryHolder) original); return original; } - @Inject(method = "lambda$reloadResources$29", at = @At("TAIL")) + @Inject(method = "lambda$reloadResources$30", at = @At("TAIL")) public void impl$onReloadedResources(final Collection $$0x, final @Coerce MinecraftServer_ReloadableResourcesAccessor $$1x, final CallbackInfo ci) { ((MinecraftServerBridge) this).bridge$reloadedServerRegistries(((SpongeRegistryHolder) $$1x.accessor$resourceManager()).registryHolder()); } diff --git a/vanilla/src/mixins/java/org/spongepowered/vanilla/mixin/core/world/level/block/FireBlockMixin_Vanilla.java b/vanilla/src/mixins/java/org/spongepowered/vanilla/mixin/core/world/level/block/FireBlockMixin_Vanilla.java index 01c0191fa31..390e94c0881 100644 --- a/vanilla/src/mixins/java/org/spongepowered/vanilla/mixin/core/world/level/block/FireBlockMixin_Vanilla.java +++ b/vanilla/src/mixins/java/org/spongepowered/vanilla/mixin/core/world/level/block/FireBlockMixin_Vanilla.java @@ -48,7 +48,7 @@ public class FireBlockMixin_Vanilla { cancellable = true) private void impl$onCatchFirePreCheck( final Level world, final BlockPos pos, final int chance, final RandomSource random, final int age, final CallbackInfo callbackInfo) { - if (!world.isClientSide) { + if (!world.isClientSide()) { if (ShouldFire.CHANGE_BLOCK_EVENT_PRE && SpongeCommonEventFactory.callChangeBlockEventPre((ServerLevelBridge) world, pos).isCancelled()) { callbackInfo.cancel(); } @@ -64,7 +64,7 @@ public class FireBlockMixin_Vanilla { cancellable = true) private void impl$onCatchFirePreCheckOther( final Level world, final BlockPos pos, final int chance, final RandomSource random, final int age, final CallbackInfo callbackInfo) { - if (!world.isClientSide) { + if (!world.isClientSide()) { if (ShouldFire.CHANGE_BLOCK_EVENT_PRE && SpongeCommonEventFactory.callChangeBlockEventPre((ServerLevelBridge) world, pos).isCancelled()) { callbackInfo.cancel(); } From b56c1176b5f12f69560add3b20d2fd1e146cfe81 Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Mon, 1 Sep 2025 16:49:56 -0700 Subject: [PATCH 02/24] chore(minecraft): update implementations for 25w32a Noticeable changes are in PlayerList management for server player loads. See: https://minecraft.wiki/w/Java_Edition_25w32a --- gradle/verification-metadata.xml | 16 ++ .../accessor/network/chat/StyleAccessor.java | 1 - .../item/stack/SpawnEggItemStackData.java | 2 - .../common/item/SpongeItemStack.java | 1 - .../server/IntegratedPlayerListMixin.java | 6 +- .../server/ServerFunctionLibraryMixin.java | 8 +- .../dedicated/DedicatedPlayerListMixin.java | 1 - ...rConfigurationPacketListenerImplMixin.java | 5 +- .../ServerLoginPacketListenerImplMixin.java | 5 +- .../config/PrepareSpawnTask_ReadyMixin.java | 98 ++++++++++++ .../core/server/players/PlayerListMixin.java | 141 +++++++----------- .../level/storage/PlayerDataStorageMixin.java | 21 --- ...erGamePacketListenerImplMixin_Tracker.java | 10 +- src/mixins/resources/mixins.sponge.core.json | 1 + 14 files changed, 187 insertions(+), 129 deletions(-) create mode 100644 src/mixins/java/org/spongepowered/common/mixin/core/server/network/config/PrepareSpawnTask_ReadyMixin.java diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 48cb727cd6e..816b55f32ef 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -1577,6 +1577,9 @@ + + + @@ -3751,6 +3754,11 @@ + + + + + @@ -3759,6 +3767,14 @@ + + + + + + + + diff --git a/src/accessors/java/org/spongepowered/common/accessor/network/chat/StyleAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/network/chat/StyleAccessor.java index cead56cb855..d79197232d8 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/network/chat/StyleAccessor.java +++ b/src/accessors/java/org/spongepowered/common/accessor/network/chat/StyleAccessor.java @@ -29,7 +29,6 @@ import net.minecraft.network.chat.HoverEvent; import net.minecraft.network.chat.Style; import net.minecraft.network.chat.TextColor; -import net.minecraft.resources.ResourceLocation; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Invoker; diff --git a/src/main/java/org/spongepowered/common/data/provider/item/stack/SpawnEggItemStackData.java b/src/main/java/org/spongepowered/common/data/provider/item/stack/SpawnEggItemStackData.java index aa2c98f0a1b..feb0d770768 100644 --- a/src/main/java/org/spongepowered/common/data/provider/item/stack/SpawnEggItemStackData.java +++ b/src/main/java/org/spongepowered/common/data/provider/item/stack/SpawnEggItemStackData.java @@ -30,12 +30,10 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.SpawnEggItem; -import net.minecraft.world.item.component.CustomData; import net.minecraft.world.item.component.TypedEntityData; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.data.Keys; import org.spongepowered.api.entity.EntityArchetype; -import org.spongepowered.common.SpongeCommon; import org.spongepowered.common.data.provider.DataProviderRegistrator; import org.spongepowered.common.entity.SpongeEntityArchetypeBuilder; diff --git a/src/main/java/org/spongepowered/common/item/SpongeItemStack.java b/src/main/java/org/spongepowered/common/item/SpongeItemStack.java index b11fb94a437..fd2224756c1 100644 --- a/src/main/java/org/spongepowered/common/item/SpongeItemStack.java +++ b/src/main/java/org/spongepowered/common/item/SpongeItemStack.java @@ -28,7 +28,6 @@ import com.google.common.collect.ImmutableList; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Dynamic; -import net.minecraft.core.Registry; import net.minecraft.core.component.DataComponentPatch; import net.minecraft.core.component.DataComponentType; import net.minecraft.core.component.DataComponents; diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/client/server/IntegratedPlayerListMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/client/server/IntegratedPlayerListMixin.java index 5e73ff153f7..a7812e8f384 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/client/server/IntegratedPlayerListMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/client/server/IntegratedPlayerListMixin.java @@ -24,7 +24,6 @@ */ package org.spongepowered.common.mixin.core.client.server; -import com.mojang.authlib.GameProfile; import net.minecraft.client.server.IntegratedPlayerList; import net.minecraft.network.chat.Component; import net.minecraft.server.players.NameAndId; @@ -48,9 +47,10 @@ public abstract class IntegratedPlayerListMixin extends PlayerListMixin implemen @Override public CompletableFuture bridge$canPlayerLoginClient(final SocketAddress param0, final com.mojang.authlib.GameProfile param1) { - final Component component = this.shadow$canPlayerLogin(param0, new NameAndId(param1)); + final var name = new NameAndId(param1); + final Component component = this.shadow$canPlayerLogin(param0, name); if (component == null) { - return this.impl$canPlayerLoginServer(param0, param1); + return this.impl$canPlayerLoginServer(param0, name); } return CompletableFuture.completedFuture(component); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/ServerFunctionLibraryMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/ServerFunctionLibraryMixin.java index ec623d2a55f..3ff191c0f0a 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/ServerFunctionLibraryMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/ServerFunctionLibraryMixin.java @@ -28,7 +28,6 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import net.minecraft.server.ServerFunctionLibrary; import net.minecraft.server.packs.resources.PreparableReloadListener; -import net.minecraft.server.packs.resources.ResourceManager; import org.spongepowered.api.Sponge; import org.spongepowered.asm.mixin.Mixin; @@ -39,10 +38,11 @@ public abstract class ServerFunctionLibraryMixin { @WrapMethod(method = "reload") - private CompletableFuture impl$onReload(final PreparableReloadListener.PreparationBarrier barrier, final ResourceManager manager, - final Executor executor1, final Executor executor2, final Operation> original) { + private CompletableFuture impl$onReload( + final PreparableReloadListener.SharedState state, final Executor executor1, + final PreparableReloadListener.PreparationBarrier barrier, Executor executor2, Operation> original) { if (Sponge.isServerAvailable()) { - return original.call(barrier, manager, executor1, executor2); + return original.call(state, executor1, barrier, executor2); } return barrier.wait(null); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedPlayerListMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedPlayerListMixin.java index 992760e055e..08c0700f7d5 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedPlayerListMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedPlayerListMixin.java @@ -24,7 +24,6 @@ */ package org.spongepowered.common.mixin.core.server.dedicated; -import com.mojang.authlib.GameProfile; import net.minecraft.core.LayeredRegistryAccess; import net.minecraft.server.MinecraftServer; import net.minecraft.server.RegistryLayer; diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerConfigurationPacketListenerImplMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerConfigurationPacketListenerImplMixin.java index a798a21ca54..2b1227d0b9c 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerConfigurationPacketListenerImplMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerConfigurationPacketListenerImplMixin.java @@ -32,6 +32,7 @@ import net.minecraft.network.protocol.configuration.ServerboundFinishConfigurationPacket; import net.minecraft.server.network.ConfigurationTask; import net.minecraft.server.network.ServerConfigurationPacketListenerImpl; +import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.PlayerList; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.event.SpongeEventFactory; @@ -137,8 +138,8 @@ public abstract class ServerConfigurationPacketListenerImplMixin extends ServerC } @Redirect(method = "handleConfigurationFinished", - at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;canPlayerLogin(Ljava/net/SocketAddress;Lcom/mojang/authlib/GameProfile;)Lnet/minecraft/network/chat/Component;")) - private Component impl$onCanPlayerLogin(final PlayerList instance, final SocketAddress $$0, final GameProfile $$1) { + at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;canPlayerLogin(Ljava/net/SocketAddress;Lnet/minecraft/server/players/NameAndId;)Lnet/minecraft/network/chat/Component;")) + private Component impl$onCanPlayerLogin(final PlayerList instance, final SocketAddress $$0, final NameAndId $$1) { //Skip as we check it at the start. return null; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerLoginPacketListenerImplMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerLoginPacketListenerImplMixin.java index db5d44ee49e..c4908d7a589 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerLoginPacketListenerImplMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerLoginPacketListenerImplMixin.java @@ -37,6 +37,7 @@ import net.minecraft.network.protocol.login.custom.CustomQueryAnswerPayload; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerLoginPacketListenerImpl; +import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.PlayerList; import net.minecraft.util.Crypt; import net.minecraft.util.CryptException; @@ -138,8 +139,8 @@ public abstract class ServerLoginPacketListenerImplMixin implements ServerLoginP } @Redirect(method = "verifyLoginAndFinishConnectionSetup", - at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;canPlayerLogin(Ljava/net/SocketAddress;Lcom/mojang/authlib/GameProfile;)Lnet/minecraft/network/chat/Component;")) - private Component impl$onCanPlayerLogin(final PlayerList instance, final SocketAddress $$0, final GameProfile $$1) { + at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;canPlayerLogin(Ljava/net/SocketAddress;Lnet/minecraft/server/players/NameAndId;)Lnet/minecraft/network/chat/Component;")) + private Component impl$onCanPlayerLogin(final PlayerList instance, final SocketAddress $$0, final NameAndId $$1) { //We check this as part of auth event. return null; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/network/config/PrepareSpawnTask_ReadyMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/config/PrepareSpawnTask_ReadyMixin.java new file mode 100644 index 00000000000..a5fa9199cd3 --- /dev/null +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/config/PrepareSpawnTask_ReadyMixin.java @@ -0,0 +1,98 @@ +/* + * 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.mixin.core.server.network.config; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.world.level.storage.ValueInput; +import org.spongepowered.api.data.Keys; +import org.spongepowered.api.entity.living.player.server.ServerPlayer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Slice; + +import java.io.IOException; +import java.time.Instant; +import java.util.Optional; +import java.util.function.Consumer; + +@Mixin(targets = "net.minecraft.server.network.config.PrepareSpawnTask$Ready") +public class PrepareSpawnTask_ReadyMixin { + + @WrapOperation( + method = "spawn", // or the mapped method containing the Player.load call + at = @At( + value = "INVOKE", + target = "Ljava/util/Optional;ifPresent(Ljava/util/function/Consumer;)V" + // If your version uses CompoundTag instead, use the proper descriptor + ) + ) + private void impl$afterPlayerLoad( + final Optional instance, final Consumer action, + final Operation original, + @Local net.minecraft.server.level.ServerPlayer player + ) throws IOException { + // Call vanilla first + original.call(instance, action); + + final ServerPlayer sPlayer = (ServerPlayer) player; + if (sPlayer.get(Keys.FIRST_DATE_JOINED).isEmpty()) { + // TODO - 25w32a changed where we have access to the Player and moved access to the data files elsewhere. +// final Path file = new File(this.playerDir, player.getStringUUID() + ".dat").toPath(); +// final Instant creationTime = java.nio.file.Files.exists(file) +// ? java.nio.file.Files.readAttributes(file, java.nio.file.attribute.BasicFileAttributes.class) +// .creationTime().toInstant() +// : null; +// +// ((SpongeServer) SpongeCommon.server()) +// .getPlayerDataManager() +// .readLegacyPlayerData(sPlayer, nbtOrValueInput, creationTime); + } + + sPlayer.offer(Keys.LAST_DATE_JOINED, java.time.Instant.now()); + } + + + @WrapOperation(method = "spawn", + at = @At(value = "INVOKE", target = "Ljava/util/Optional;ifPresent(Ljava/util/function/Consumer;)V"), + slice = @Slice( + from = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;loadPlayerData(Lnet/minecraft/server/players/NameAndId;)Ljava/util/Optional;"), + to = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;snapTo(Lnet/minecraft/world/phys/Vec3;FF)V") + ) + ) + private void impl$setPlayerDataForNewPlayers( + final Optional instance, final Consumer action, + final Operation original, + @Local final net.minecraft.server.level.ServerPlayer playerIn + ) { + original.call(instance, action); + if (instance.isEmpty()) { + final Instant now = Instant.now(); + ((ServerPlayer) playerIn).offer(Keys.FIRST_DATE_JOINED, now); + ((ServerPlayer) playerIn).offer(Keys.LAST_DATE_JOINED, now); + } + } +} diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java index c92827a40e2..d4c996cfcf0 100755 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java @@ -24,6 +24,8 @@ */ package org.spongepowered.common.mixin.core.server.players; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Local; import io.netty.channel.local.LocalAddress; import net.kyori.adventure.audience.Audience; @@ -47,17 +49,14 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.network.CommonListenerCookie; import net.minecraft.server.players.IpBanList; +import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.PlayerList; import net.minecraft.server.players.UserBanList; import net.minecraft.server.players.UserWhiteList; -import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.Level; import net.minecraft.world.level.border.BorderChangeListener; import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.portal.TeleportTransition; -import net.minecraft.world.level.storage.PlayerDataStorage; -import net.minecraft.world.level.storage.ValueInput; import org.checkerframework.checker.nullness.qual.Nullable; import org.objectweb.asm.Opcodes; import org.slf4j.Logger; @@ -130,9 +129,7 @@ import java.util.Collection; import java.util.Date; import java.util.List; -import java.util.Map; import java.util.Optional; -import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.function.Function; import java.util.function.Predicate; @@ -149,17 +146,14 @@ public abstract class PlayerListMixin implements PlayerListBridge { @Shadow @Final @Mutable private UserWhiteList whitelist; @Shadow @Final private List players; @Shadow @Final protected int maxPlayers; - @Shadow @Final private Map playersByUUID; - @Shadow @Final private PlayerDataStorage playerIo; - @Shadow public abstract MinecraftServer shadow$getServer(); - @Shadow public abstract Optional shadow$load(final net.minecraft.server.level.ServerPlayer $$0, final ProblemReporter $$1); - @Shadow public abstract boolean shadow$canBypassPlayerLimit(com.mojang.authlib.GameProfile param0); + @Shadow public abstract boolean shadow$canBypassPlayerLimit(NameAndId $$0); @Shadow protected abstract boolean shadow$verifyChatTrusted(final PlayerChatMessage $$0); @Shadow protected abstract void shadow$broadcastChatMessage(final PlayerChatMessage $$0, final Predicate $$1, final net.minecraft.server.level.@Nullable ServerPlayer $$2, final ChatType.Bound $$4); // @formatter:on + private boolean impl$isRespawnWithPosition = false; private boolean impl$isDuringSystemMessageEvent = false; @@ -175,10 +169,10 @@ public abstract class PlayerListMixin implements PlayerListBridge { if (this instanceof IntegratedPlayerListBridge) { return ((IntegratedPlayerListBridge) this).bridge$canPlayerLoginClient(param0, param1); } - return this.impl$canPlayerLoginServer(param0, param1); + return this.impl$canPlayerLoginServer(param0, new NameAndId(param1)); } - protected final CompletableFuture impl$canPlayerLoginServer(final SocketAddress param0, final com.mojang.authlib.GameProfile param1) { + protected final CompletableFuture impl$canPlayerLoginServer(final SocketAddress param0, final NameAndId param1) { final SpongeGameProfile profile = SpongeGameProfile.basicOf(param1); return Sponge.server().serviceProvider().banService().find(profile).thenCompose(profileBanOpt -> { @@ -219,7 +213,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { return CompletableFuture.completedFuture(null); } final PermissionService permissionService = Sponge.server().serviceProvider().permissionService(); - return permissionService.userSubjects().loadSubject(param1.getId().toString()).handle((subject, ex) -> { + return permissionService.userSubjects().loadSubject(param1.id().toString()).handle((subject, ex) -> { if (ex == null) { return subject.hasPermission(LoginPermissions.BYPASS_WHITELIST_PERMISSION); } @@ -248,31 +242,16 @@ public abstract class PlayerListMixin implements PlayerListBridge { }, SpongeCommon.server()); } - @Redirect(method = "placeNewPlayer", - at = @At(value = "INVOKE", - target = "Lnet/minecraft/server/players/PlayerList;load(Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/util/ProblemReporter;)Ljava/util/Optional;" - ) - ) - private Optional impl$setPlayerDataForNewPlayers( - final PlayerList playerList, final net.minecraft.server.level.ServerPlayer playerIn, - final ProblemReporter problemReporter - ) { - final Optional compound = this.shadow$load(playerIn, problemReporter); - if (compound.isEmpty()) { - final Instant now = Instant.now(); - ((ServerPlayer) playerIn).offer(Keys.FIRST_DATE_JOINED, now); - ((ServerPlayer) playerIn).offer(Keys.LAST_DATE_JOINED, now); - } - return compound; - } - @Redirect(method = "placeNewPlayer", + @WrapOperation(method = "placeNewPlayer", at = @At(value = "INVOKE", - target = "Lnet/minecraft/server/MinecraftServer;getLevel(Lnet/minecraft/resources/ResourceKey;)Lnet/minecraft/server/level/ServerLevel;" + target = "Lnet/minecraft/server/level/ServerPlayer;level()Lnet/minecraft/server/level/ServerLevel;" ) ) - private net.minecraft.server.level.ServerLevel impl$onInitPlayer_getWorld(final MinecraftServer minecraftServer, - final ResourceKey dimension, final Connection networkManager, final net.minecraft.server.level.ServerPlayer mcPlayer + private net.minecraft.server.level.ServerLevel impl$onInitPlayer_getWorld( + final net.minecraft.server.level.ServerPlayer instance, final Operation original, + final Connection networkManager, final net.minecraft.server.level.ServerPlayer mcPlayer, + final CommonListenerCookie ci ) { final net.minecraft.network.chat.@Nullable Component kickReason = ((ConnectionBridge) networkManager).bridge$getKickReason(); final Component disconnectMessage; @@ -282,12 +261,12 @@ public abstract class PlayerListMixin implements PlayerListBridge { disconnectMessage = Component.text("You are not allowed to log in to this server."); } - net.minecraft.server.level.ServerLevel mcWorld = minecraftServer.getLevel(dimension); + net.minecraft.server.level.ServerLevel mcWorld = original.call(instance); if (mcWorld == null) { SpongeCommon.logger().warn("The player '{}' was located in a world that isn't loaded or doesn't exist. This is not safe so " - + "the player will be moved to the spawn of the default world.", mcPlayer.getGameProfile().getName()); - mcWorld = minecraftServer.overworld(); + + "the player will be moved to the spawn of the default world.", mcPlayer.getGameProfile().getName()); + mcWorld = this.server.overworld(); final BlockPos spawnPoint = mcWorld.getSharedSpawnPos(); mcPlayer.setPos(spawnPoint.getX() + 0.5, spawnPoint.getY() + 0.5, spawnPoint.getZ() + 0.5); } @@ -305,7 +284,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { final Cause cause = Cause.of(EventContext.empty(), connection, user); final ServerSideConnectionEvent.Login event = SpongeEventFactory.createServerSideConnectionEventLogin(cause, disconnectMessage, - disconnectMessage, location, location, rotation, rotation, connection, SpongeGameProfile.of(mcPlayer.getGameProfile()), user); + disconnectMessage, location, location, rotation, rotation, connection, SpongeGameProfile.of(mcPlayer.getGameProfile()), user); if (kickReason != null) { event.setCancelled(true); } @@ -317,15 +296,17 @@ public abstract class PlayerListMixin implements PlayerListBridge { final ServerLocation toLocation = event.toLocation(); final Vector3d toRotation = event.toRotation(); mcPlayer.absSnapTo(toLocation.x(), toLocation.y(), toLocation.z(), - (float) toRotation.y(), (float) toRotation.x()); - return (net.minecraft.server.level.ServerLevel) toLocation.world(); + (float) toRotation.y(), (float) toRotation.x()); + final var level = (ServerLevel) toLocation.world(); + instance.setServerLevel(level); + return level; } @Inject(method = "placeNewPlayer", cancellable = true, at = @At( value = "INVOKE", - target = "Lnet/minecraft/server/MinecraftServer;getLevel(Lnet/minecraft/resources/ResourceKey;)Lnet/minecraft/server/level/ServerLevel;", + target = "Lnet/minecraft/server/level/ServerPlayer;level()Lnet/minecraft/server/level/ServerLevel;", shift = At.Shift.AFTER ) ) @@ -342,9 +323,9 @@ public abstract class PlayerListMixin implements PlayerListBridge { ) ) private void impl$onInitPlayer_printPlayerWorldInJoinFeedback(final org.slf4j.Logger logger, final String s, final Object[] objects, - final Connection conn, final net.minecraft.server.level.ServerPlayer player) { + final Connection conn, final net.minecraft.server.level.ServerPlayer player) { logger.info("{}[{}] logged in to world '{}' with entity id {} at ({}, {}, {})", player.getName().getString(), player, - ((ServerWorld)player.level()).key(), player.getId(), player.getX(), player.getY(), player.getZ()); + ((ServerWorld) player.level()).key(), player.getId(), player.getX(), player.getY(), player.getZ()); } @Redirect(method = "placeNewPlayer", @@ -378,7 +359,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { ) ) private void impl$onInitPlayer_delaySendMessage(final PlayerList instance, final net.minecraft.network.chat.Component message, - final boolean $$1, final Connection manager, final net.minecraft.server.level.ServerPlayer playerIn + final boolean $$1, final Connection manager, final net.minecraft.server.level.ServerPlayer playerIn ) { // Don't send here, will be done later. We cache the expected message. ((ServerPlayerBridge) playerIn).bridge$setConnectionMessageToSend(message); @@ -391,13 +372,13 @@ public abstract class PlayerListMixin implements PlayerListBridge { @Redirect(method = "placeNewPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getCustomBossEvents()Lnet/minecraft/server/bossevents/CustomBossEvents;")) private CustomBossEvents impl$getPerWorldBossBarManager( - final MinecraftServer minecraftServer, final Connection netManager, final net.minecraft.server.level.ServerPlayer playerIn) { + final MinecraftServer minecraftServer, final Connection netManager, final net.minecraft.server.level.ServerPlayer playerIn) { return ((ServerLevelBridge) playerIn.level()).bridge$getBossBarManager(); } @Redirect(method = "placeNewPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;updateEntireScoreboard(Lnet/minecraft/server/ServerScoreboard;Lnet/minecraft/server/level/ServerPlayer;)V")) private void impl$sendScoreboard(final PlayerList playerList, final ServerScoreboard scoreboardIn, final net.minecraft.server.level.ServerPlayer playerIn) { - ((ServerPlayerBridge)playerIn).bridge$initScoreboard(); + ((ServerPlayerBridge) playerIn).bridge$initScoreboard(); } @Redirect( @@ -408,7 +389,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { ) ) private void impl$onlySendSelfAddPlayerOnVanished(final PlayerList playerList, final Packet addPlayer, - final Connection playerConnection, final net.minecraft.server.level.ServerPlayer serverPlayer + final Connection playerConnection, final net.minecraft.server.level.ServerPlayer serverPlayer ) { if (((VanishableBridge) serverPlayer).bridge$vanishState().invisible()) { serverPlayer.connection.send(addPlayer); @@ -441,7 +422,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { final Component joinComponent = SpongeAdventure.asAdventure(((ServerPlayerBridge) mcPlayer).bridge$getConnectionMessageToSend()); final ServerSideConnectionEvent.Join event = SpongeEventFactory.createServerSideConnectionEventJoin(cause, audience, - Optional.of(audience), joinComponent, joinComponent, connection, player, SpongeGameProfile.of(mcPlayer.getGameProfile()), false); + Optional.of(audience), joinComponent, joinComponent, connection, player, SpongeGameProfile.of(mcPlayer.getGameProfile()), false); SpongeCommon.post(event); if (!event.isMessageCancelled()) { event.audience().ifPresent(audience1 -> audience1.sendMessage(Identity.nil(), event.message())); @@ -481,29 +462,13 @@ public abstract class PlayerListMixin implements PlayerListBridge { worldBorder.addListener(new PerWorldBorderListener(serverWorld)); } - @Redirect(method = "load", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/level/ServerPlayer;load(Lnet/minecraft/world/level/storage/ValueInput;)V" - ) - ) - private void impl$setSpongePlayerDataForSinglePlayer(final net.minecraft.server.level.ServerPlayer entity, final ValueInput compound) { - entity.load(compound); - - if (((ServerPlayer) entity).get(Keys.FIRST_DATE_JOINED).isEmpty()) { - ((SpongeServer) this.shadow$getServer()).getPlayerDataManager().readLegacyPlayerData((ServerPlayer) entity, compound, null); - } - - ((ServerPlayer) entity).offer(Keys.LAST_DATE_JOINED, Instant.now()); - } - @Inject(method = "respawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;findRespawnPositionAndUseSpawnBlock(ZLnet/minecraft/world/level/portal/TeleportTransition$PostTeleportTransition;)Lnet/minecraft/world/level/portal/TeleportTransition;" ) ) private void impl$flagIfRespawnPositionIsGameMechanic(final net.minecraft.server.level.ServerPlayer $$0, final boolean $$1, - final Entity.RemovalReason $$2, final CallbackInfoReturnable cir) { + final Entity.RemovalReason $$2, final CallbackInfoReturnable cir) { this.impl$isRespawnWithPosition = $$0.getRespawnConfig() != null; } @@ -516,7 +481,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { ) ) private double impl$callRespawnPlayerRecreateEvent(final net.minecraft.server.level.ServerPlayer newPlayer, - final net.minecraft.server.level.ServerPlayer player, final boolean keepAllPlayerData, final @Local TeleportTransition dimensionTransition) { + final net.minecraft.server.level.ServerPlayer player, final boolean keepAllPlayerData, final @Local TeleportTransition dimensionTransition) { final ServerPlayer originalPlayer = (ServerPlayer) player; final ServerPlayer recreatedPlayer = (ServerPlayer) newPlayer; @@ -526,9 +491,9 @@ public abstract class PlayerListMixin implements PlayerListBridge { final ServerWorld destinationWorld = recreatedPlayer.world(); final RespawnPlayerEvent.Recreate event = SpongeEventFactory.createRespawnPlayerEventRecreate(PhaseTracker.getInstance().currentCause(), - destinationPosition, originalWorld, originalPosition, destinationWorld, - (ServerWorld) dimensionTransition.newLevel(), - destinationPosition, originalPlayer, recreatedPlayer, this.impl$isRespawnWithPosition, !keepAllPlayerData); + destinationPosition, originalWorld, originalPosition, destinationWorld, + (ServerWorld) dimensionTransition.newLevel(), + destinationPosition, originalPlayer, recreatedPlayer, this.impl$isRespawnWithPosition, !keepAllPlayerData); SpongeCommon.post(event); this.impl$isRespawnWithPosition = false; @@ -555,18 +520,18 @@ public abstract class PlayerListMixin implements PlayerListBridge { @Inject(method = "respawn", at = @At("RETURN")) private void impl$callRespawnPlayerPostEvent(final net.minecraft.server.level.ServerPlayer player, final boolean $$1, final Entity.RemovalReason $$2, - final CallbackInfoReturnable cir, final @Local TeleportTransition dimensionTransition) { + final CallbackInfoReturnable cir, final @Local TeleportTransition dimensionTransition) { final ServerPlayer recreatedPlayer = (ServerPlayer) cir.getReturnValue(); final ServerWorld originalWorld = (ServerWorld) player.level(); final RespawnPlayerEvent.Post event = SpongeEventFactory.createRespawnPlayerEventPost(PhaseTracker.getInstance().currentCause(), - recreatedPlayer.world(), originalWorld, (ServerWorld) dimensionTransition.newLevel(), recreatedPlayer); + recreatedPlayer.world(), originalWorld, (ServerWorld) dimensionTransition.newLevel(), recreatedPlayer); SpongeCommon.post(event); } @Redirect(method = "sendLevelInfo", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;overworld()Lnet/minecraft/server/level/ServerLevel;")) private ServerLevel impl$usePerWorldWorldBorder(final MinecraftServer minecraftServer, final net.minecraft.server.level.ServerPlayer playerIn, - final ServerLevel worldIn) { + final ServerLevel worldIn) { return worldIn; } @@ -574,8 +539,8 @@ public abstract class PlayerListMixin implements PlayerListBridge { final net.minecraft.network.chat.Component reason = SpongeAdventure.asVanilla(disconnectMessage); try { - PlayerListMixin.LOGGER.info("Disconnecting " + (profile != null ? profile.toString() + " (" + netManager.getRemoteAddress().toString() + ")" : - netManager.getRemoteAddress() + ": " + reason.getString())); + PlayerListMixin.LOGGER.info("Disconnecting " + (profile != null ? profile + " (" + netManager.getRemoteAddress() + ")" : + netManager.getRemoteAddress() + ": " + reason.getString())); netManager.send(new ClientboundDisconnectPacket(reason)); netManager.disconnect(reason); } catch (final Exception exception) { @@ -589,9 +554,9 @@ public abstract class PlayerListMixin implements PlayerListBridge { } @Inject(method = "broadcastSystemMessage(Lnet/minecraft/network/chat/Component;Ljava/util/function/Function;Z)V", - at = @At("HEAD"), cancellable = true) + at = @At("HEAD"), cancellable = true) private void impl$onBroadcastSystemMessage(final net.minecraft.network.chat.Component $$0, - final Function $$1, final boolean $$2, final CallbackInfo ci) { + final Function $$1, final boolean $$2, final CallbackInfo ci) { if (this.impl$isDuringSystemMessageEvent) { return; } @@ -600,7 +565,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { final Audience originalAudience = (Audience) this.server; final Component originalMessage = SpongeAdventure.asAdventure($$0); final SystemMessageEvent event = SpongeEventFactory.createSystemMessageEvent(PhaseTracker.getInstance().currentCause(), - originalAudience, Optional.of(originalAudience), originalMessage, originalMessage); + originalAudience, Optional.of(originalAudience), originalMessage, originalMessage); if (SpongeCommon.post(event)) { ci.cancel(); return; @@ -612,23 +577,23 @@ public abstract class PlayerListMixin implements PlayerListBridge { } @Redirect(method = "broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/network/chat/ChatType$Bound;)V", - at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Ljava/util/function/Predicate;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/network/chat/ChatType$Bound;)V")) + at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Ljava/util/function/Predicate;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/network/chat/ChatType$Bound;)V")) private void impl$onBroadcastChatMessage1(final PlayerList instance, final PlayerChatMessage $$0, - final Predicate $$1, final net.minecraft.server.level.ServerPlayer $$2, - final ChatType.Bound $$4) { + final Predicate $$1, final net.minecraft.server.level.ServerPlayer $$2, + final ChatType.Bound $$4) { this.impl$onBroadcastChatMessage($$0, $$1, $$2, $$4); } @Redirect(method = "broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Lnet/minecraft/commands/CommandSourceStack;Lnet/minecraft/network/chat/ChatType$Bound;)V", - at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Ljava/util/function/Predicate;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/network/chat/ChatType$Bound;)V")) + at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastChatMessage(Lnet/minecraft/network/chat/PlayerChatMessage;Ljava/util/function/Predicate;Lnet/minecraft/server/level/ServerPlayer;Lnet/minecraft/network/chat/ChatType$Bound;)V")) private void impl$onBroadcastChatMessage2(final PlayerList instance, final PlayerChatMessage $$0, - final Predicate $$1, final net.minecraft.server.level.ServerPlayer $$2, - final ChatType.Bound $$4) { + final Predicate $$1, final net.minecraft.server.level.ServerPlayer $$2, + final ChatType.Bound $$4) { this.impl$onBroadcastChatMessage($$0, $$1, $$2, $$4); } private void impl$onBroadcastChatMessage(final PlayerChatMessage $$0, final Predicate $$1, - final net.minecraft.server.level.ServerPlayer $$2, final ChatType.Bound $$4) { + final net.minecraft.server.level.ServerPlayer $$2, final ChatType.Bound $$4) { final boolean isTrusted = this.shadow$verifyChatTrusted($$0); @@ -647,12 +612,12 @@ public abstract class PlayerListMixin implements PlayerListBridge { } final PlayerChatEvent.Submit event = SpongeEventFactory.createPlayerChatEventSubmit(frame.currentCause(), content, content, chatType, - Optional.empty(), Optional.ofNullable((ServerPlayer) $$2), sender, Optional.ofNullable(target), isTrusted); + Optional.empty(), Optional.ofNullable((ServerPlayer) $$2), sender, Optional.ofNullable(target), isTrusted); if (SpongeCommon.post(event)) { return; // Do nothing when canceled or audience removed } boundChatType = ChatType.bind(ResourceKey.create(Registries.CHAT_TYPE, (ResourceLocation) (Object) event.chatType().location()), - this.server.registryAccess(), SpongeAdventure.asVanilla(event.sender())); + this.server.registryAccess(), SpongeAdventure.asVanilla(event.sender())); boundChatType = event.target().map(SpongeAdventure::asVanilla).map(boundChatType::withTargetName).orElse(boundChatType); filter = event.filter().map(f -> $$1.and((Predicate) f)).orElse($$1); @@ -663,7 +628,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { // The value of `isTrusted` will always be `true` when `online-mode=true`. // If `online-mode=false`, then `isTrusted` will also have a value of `false`. // When `online-mode=false`, the player is not shown a notification when the server changes the message. - var modifiedMessage = new PlayerChatMessage($$0.link(), $$0.signature(), $$0.signedBody(), customMessage, $$0.filterMask()); + var modifiedMessage = new PlayerChatMessage($$0.link(), $$0.signature(), $$0.signedBody(), customMessage, $$0.filterMask()); this.shadow$broadcastChatMessage(modifiedMessage, filter, $$2, boundChatType); return; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/storage/PlayerDataStorageMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/storage/PlayerDataStorageMixin.java index b5be3ddb4a3..b695562105d 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/storage/PlayerDataStorageMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/storage/PlayerDataStorageMixin.java @@ -24,14 +24,8 @@ */ package org.spongepowered.common.mixin.core.world.level.storage; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.mojang.datafixers.DataFixer; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.util.datafix.DataFixTypes; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.storage.PlayerDataStorage; -import org.spongepowered.api.data.Keys; import org.spongepowered.api.entity.living.player.server.ServerPlayer; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -43,11 +37,6 @@ import org.spongepowered.common.SpongeServer; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.attribute.BasicFileAttributes; -import java.time.Instant; @Mixin(PlayerDataStorage.class) public abstract class PlayerDataStorageMixin { @@ -56,16 +45,6 @@ public abstract class PlayerDataStorageMixin { @Shadow @Final private File playerDir; // @formatter:on - @Redirect(method = "lambda$load$1", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;load(Lnet/minecraft/world/level/storage/ValueInput;)V")) - private void impl$readSpongePlayerData(final Player playerEntity, final ValueInput compound) throws IOException { - playerEntity.load(compound); - if (((ServerPlayer) playerEntity).get(Keys.FIRST_DATE_JOINED).isEmpty()) { - final Path file = new File(this.playerDir, playerEntity.getStringUUID() + ".dat").toPath(); - final Instant creationTime = Files.exists(file) ? Files.readAttributes(file, BasicFileAttributes.class).creationTime().toInstant() : null; - ((SpongeServer) SpongeCommon.server()).getPlayerDataManager().readLegacyPlayerData((ServerPlayer) playerEntity, compound, creationTime); - } - ((ServerPlayer) playerEntity).offer(Keys.LAST_DATE_JOINED, Instant.now()); - } @Inject(method = "save", at = @At(value = "INVOKE", diff --git a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/network/ServerGamePacketListenerImplMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/network/ServerGamePacketListenerImplMixin_Tracker.java index 1d3906024cb..a4d511670ec 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/network/ServerGamePacketListenerImplMixin_Tracker.java +++ b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/network/ServerGamePacketListenerImplMixin_Tracker.java @@ -24,6 +24,8 @@ */ package org.spongepowered.common.mixin.tracker.server.network; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayerGameMode; @@ -54,17 +56,17 @@ public abstract class ServerGamePacketListenerImplMixin_Tracker { @Shadow public ServerPlayer player; - @Redirect(method = "tick", + @WrapOperation(method = "tickPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;doTick()V")) - private void tracker$wrapPlayerTickWithPhase(final ServerPlayer player) { + private void tracker$wrapPlayerTickWithPhase(ServerPlayer instance, Operation original) { if (((PlatformEntityBridge) player).bridge$isFakePlayer() || ((LevelBridge) player.level()).bridge$isFake()) { - player.doTick(); + original.call(instance); return; } try (final PlayerTickContext context = TickPhase.Tick.PLAYER.createPhaseContext(PhaseTracker.getWorldInstance(this.player.level())).source(player)) { context.buildAndSwitch(); PhaseTracker.LOGGER.trace(TrackingUtil.PLAYER_TICK, () -> "Wrapping Player Tick: " + player.toString()); - player.doTick(); + original.call(instance); } } diff --git a/src/mixins/resources/mixins.sponge.core.json b/src/mixins/resources/mixins.sponge.core.json index 3ef7ba1cc51..d6084a47817 100644 --- a/src/mixins/resources/mixins.sponge.core.json +++ b/src/mixins/resources/mixins.sponge.core.json @@ -95,6 +95,7 @@ "server.network.ServerHandshakePacketListenerImplMixin", "server.network.ServerLoginPacketListenerImplMixin", "server.network.ServerStatusPacketListenerImplMixin", + "server.network.config.PrepareSpawnTask_ReadyMixin", "server.packs.resoruces.MultiPackResourceManagerMixin", "server.players.BanListEntryMixin", "server.players.GameProfileCache_GameProfileInfoMixin", From c96cd45173f22196d0f8265c2b6296d2bf3bf8f4 Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Mon, 1 Sep 2025 18:03:24 -0700 Subject: [PATCH 03/24] chore(minecraft): update to 25w33a Notes: - Added an implementation shortfall for the new explosion handling, see https://github.com/SpongePowered/SpongeAPI/issues/2599 See: https://minecraft.wiki/w/Java_Edition_25w33a --- SpongeAPI | 2 +- .../world/level/block/BlockRegistries.java | 2 +- gradle.properties | 2 +- .../block/state/BlockStateDataProvider.java | 13 ++++---- .../event/tracking/phase/tick/TickPhase.java | 2 +- .../core/server/level/ServerLevelMixin.java | 5 +-- .../level/ServerLevelMixin_Tracker.java | 32 ++++++++++--------- 7 files changed, 31 insertions(+), 27 deletions(-) diff --git a/SpongeAPI b/SpongeAPI index 6252dce257b..b121463d867 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit 6252dce257b18be1897b5c07d946ff2886fbf79b +Subproject commit b121463d867d4d0d65b04d77da285fca6beecd37 diff --git a/generator/src/main/java/org/spongepowered/vanilla/generator/world/level/block/BlockRegistries.java b/generator/src/main/java/org/spongepowered/vanilla/generator/world/level/block/BlockRegistries.java index 59d1f58a69c..1a7e8938a0b 100644 --- a/generator/src/main/java/org/spongepowered/vanilla/generator/world/level/block/BlockRegistries.java +++ b/generator/src/main/java/org/spongepowered/vanilla/generator/world/level/block/BlockRegistries.java @@ -110,7 +110,7 @@ public static List enumRegistries(final Context context) { ), new EnumEntriesValidator<>( "data.type", - "CopperOxidization", + "CopperOxidations", WeatheringCopper.WeatherState.class, "getSerializedName", "sponge" diff --git a/gradle.properties b/gradle.properties index 335000978ef..d81f4121e3f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.c mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json superClassChanges=common.superclasschange -minecraftVersion=25w32a +minecraftVersion=25w33a recommendedVersion=0-SNAPSHOT org.gradle.dependency.verification.console=verbose diff --git a/src/main/java/org/spongepowered/common/data/provider/block/state/BlockStateDataProvider.java b/src/main/java/org/spongepowered/common/data/provider/block/state/BlockStateDataProvider.java index dd2d82f4c66..d51022054f1 100644 --- a/src/main/java/org/spongepowered/common/data/provider/block/state/BlockStateDataProvider.java +++ b/src/main/java/org/spongepowered/common/data/provider/block/state/BlockStateDataProvider.java @@ -49,6 +49,7 @@ public static void register(final DataProviderRegistrator registrator) { BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.AGE_4, BlockStateProperties.AGE_4); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.AGE_5, BlockStateProperties.AGE_5); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.AGE_7, BlockStateProperties.AGE_7); + BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.ALIGN_ITEMS_TO_BOTTOM, BlockStateProperties.ALIGN_ITEMS_TO_BOTTOM); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.ATTACHED, BlockStateProperties.ATTACHED); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.ATTACH_FACE, BlockStateProperties.ATTACH_FACE); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.AXIS, BlockStateProperties.AXIS); @@ -62,12 +63,6 @@ public static void register(final DataProviderRegistrator registrator) { BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CANDLES, BlockStateProperties.CANDLES); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CAN_SUMMON, BlockStateProperties.CAN_SUMMON); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CHEST_TYPE, BlockStateProperties.CHEST_TYPE); - BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CHISELED_BOOKSHELF_SLOT_0_OCCUPIED, BlockStateProperties.CHISELED_BOOKSHELF_SLOT_0_OCCUPIED); - BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CHISELED_BOOKSHELF_SLOT_1_OCCUPIED, BlockStateProperties.CHISELED_BOOKSHELF_SLOT_1_OCCUPIED); - BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CHISELED_BOOKSHELF_SLOT_2_OCCUPIED, BlockStateProperties.CHISELED_BOOKSHELF_SLOT_2_OCCUPIED); - BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CHISELED_BOOKSHELF_SLOT_3_OCCUPIED, BlockStateProperties.CHISELED_BOOKSHELF_SLOT_3_OCCUPIED); - BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CHISELED_BOOKSHELF_SLOT_4_OCCUPIED, BlockStateProperties.CHISELED_BOOKSHELF_SLOT_4_OCCUPIED); - BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CHISELED_BOOKSHELF_SLOT_5_OCCUPIED, BlockStateProperties.CHISELED_BOOKSHELF_SLOT_5_OCCUPIED); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CONDITIONAL, BlockStateProperties.CONDITIONAL); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.COPPER_GOLEM_POSE, BlockStateProperties.COPPER_GOLEM_POSE); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CRACKED, BlockStateProperties.CRACKED); @@ -143,6 +138,12 @@ public static void register(final DataProviderRegistrator registrator) { BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SIDE_CHAIN_PART, BlockStateProperties.SIDE_CHAIN_PART); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SIGNAL_FIRE, BlockStateProperties.SIGNAL_FIRE); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SLAB_TYPE, BlockStateProperties.SLAB_TYPE); + BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SLOT_0_OCCUPIED, BlockStateProperties.SLOT_0_OCCUPIED); + BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SLOT_1_OCCUPIED, BlockStateProperties.SLOT_1_OCCUPIED); + BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SLOT_2_OCCUPIED, BlockStateProperties.SLOT_2_OCCUPIED); + BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SLOT_3_OCCUPIED, BlockStateProperties.SLOT_3_OCCUPIED); + BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SLOT_4_OCCUPIED, BlockStateProperties.SLOT_4_OCCUPIED); + BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SLOT_5_OCCUPIED, BlockStateProperties.SLOT_5_OCCUPIED); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SNOWY, BlockStateProperties.SNOWY); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SOUTH, BlockStateProperties.SOUTH); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.SOUTH_REDSTONE, BlockStateProperties.SOUTH_REDSTONE); diff --git a/src/main/java/org/spongepowered/common/event/tracking/phase/tick/TickPhase.java b/src/main/java/org/spongepowered/common/event/tracking/phase/tick/TickPhase.java index aee13b8e122..080a96839b6 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/phase/tick/TickPhase.java +++ b/src/main/java/org/spongepowered/common/event/tracking/phase/tick/TickPhase.java @@ -40,7 +40,7 @@ public static final class Tick { public static final IPhaseState TILE_ENTITY = new TileEntityTickPhaseState(); public static final IPhaseState BLOCK_EVENT = new BlockEventTickPhaseState(); public static final IPhaseState PLAYER = new PlayerTickPhaseState(); - public static final IPhaseState WEATHER = new WeatherTickPhaseState(); + public static final IPhaseState WEATHER = new WeatherTickPhaseState(); public static final IPhaseState SERVER_TICK = new ServerTickState(); public static final IPhaseState WORLD_TICK = new WorldTickState(); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java index 9c7f5dde43b..4425ab67848 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java @@ -48,6 +48,7 @@ import net.minecraft.server.players.PlayerList; import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvents; +import net.minecraft.util.random.WeightedList; import net.minecraft.world.RandomSequences; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.ai.village.poi.PoiManager; @@ -275,7 +276,7 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerLevel for (ServerPlayer player : this.players) { if (player.distanceToSqr(mcExplosion.center()) < 4096.0) { Optional kb = Optional.ofNullable(mcExplosion.getHitPlayers().get(player)); - final var packet = new ClientboundExplodePacket(mcExplosion.center(), kb, particle, sound); + final var packet = new ClientboundExplodePacket(mcExplosion.center(), explosion.radius(), 1, kb, particle, sound, WeightedList.of()); this.bridge$handleExplosionPacket(player.connection, explosion, packet); player.connection.send(packet); } @@ -292,7 +293,7 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerLevel var soundEvent = Holder.direct(new SoundEvent(ResourceLocation.parse("sponge:none"), Optional.of(0f))); // "no" sound soundEvent = packet.explosionSound(); // TODO apiExplosion.shouldPlaySmoke() is not initialized correctly - var newPacket = new ClientboundExplodePacket(packet.center(), packet.playerKnockback(), particleData, soundEvent); + var newPacket = new ClientboundExplodePacket(packet.center(), packet.radius(), packet.blockCount(), packet.playerKnockback(), particleData, soundEvent, packet.blockParticles()); instance.send(newPacket); } @Override diff --git a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerLevelMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerLevelMixin_Tracker.java index e003846fac5..d5867c90ef8 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerLevelMixin_Tracker.java +++ b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerLevelMixin_Tracker.java @@ -30,6 +30,7 @@ import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; +import net.minecraft.core.particles.ExplosionParticleInfo; import net.minecraft.core.particles.ParticleOptions; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.PacketListener; @@ -40,6 +41,7 @@ import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.sounds.SoundEvent; import net.minecraft.util.RandomSource; +import net.minecraft.util.random.WeightedList; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.damagesource.DamageSource; @@ -313,9 +315,9 @@ public abstract class ServerLevelMixin_Tracker extends LevelMixin_Tracker implem private org.spongepowered.api.world.explosion.Explosion tracker$apiExplosion; - @Redirect(method = "explode", at = @At(value = "INVOKE", - target = "Lnet/minecraft/world/level/ServerExplosion;explode()V")) - private void tracker$onExplode(final ServerExplosion instance) { + @WrapOperation(method = "explode", at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/level/ServerExplosion;explode()I")) + private int tracker$onExplode(ServerExplosion instance, Operation original) { var mcExplosion = instance; final var entity = instance.getDirectSourceEntity(); // TODO entity can be null, what is our API explosive then? @@ -327,21 +329,21 @@ public abstract class ServerLevelMixin_Tracker extends LevelMixin_Tracker implem if (!(entity instanceof final Explosive apiExplosive)) { mcExplosion.explode(); this.tracker$apiExplosion = explosionBuilder.build(); - return; + return 0; } final PhaseTracker phaseTracker = PhaseTracker.getWorldInstance((ServerLevel) (Object) this); final var detonateEvent = SpongeEventFactory.createDetonateExplosiveEvent(phaseTracker.currentCause(), explosionBuilder, apiExplosive, (org.spongepowered.api.world.explosion.Explosion) instance); if (Sponge.eventManager().post(detonateEvent)) { this.tracker$cancelExplosionEffects(entity); - return; + return 0; } // Build the explosion from event var apiExplosion = detonateEvent.explosionBuilder().build(); if (apiExplosion.radius() <= 0) { this.tracker$cancelExplosionEffects(entity); - return; + return 0; } if (ShouldFire.EXPLOSION_EVENT_PRE) { @@ -350,7 +352,7 @@ public abstract class ServerLevelMixin_Tracker extends LevelMixin_Tracker implem SpongeEventFactory.createExplosionEventPre(phaseTracker.currentCause(), apiExplosion, thisWorld); if (SpongeCommon.post(event)) { this.tracker$cancelExplosionEffects(entity); - return; + return 0; } try { @@ -365,18 +367,17 @@ public abstract class ServerLevelMixin_Tracker extends LevelMixin_Tracker implem } } + this.tracker$apiExplosion = apiExplosion; try (final PhaseContext<@NonNull ?> ctx = GeneralPhase.State.EXPLOSION.createPhaseContext(phaseTracker).explosion(mcExplosion) .source(((Optional) apiExplosion.sourceExplosive()).orElse(this))) { ctx.buildAndSwitch(); - mcExplosion.explode(); + return original.call(mcExplosion); } - - this.tracker$apiExplosion = apiExplosion; } @Inject(method = "explode", cancellable = true, at = @At(value = "INVOKE", - target = "Lnet/minecraft/world/level/ServerExplosion;explode()V", shift = At.Shift.AFTER)) + target = "Lnet/minecraft/world/level/ServerExplosion;explode()I", shift = At.Shift.AFTER)) private void tracker$onCancelled(final CallbackInfo ci) { if (this.tracker$apiExplosion == null) { ci.cancel(); @@ -394,10 +395,11 @@ public abstract class ServerLevelMixin_Tracker extends LevelMixin_Tracker implem } @Inject(method = "explode", at = @At(value = "RETURN")) - private void tracker$afterExplodeCleanup(final Entity $$0, final DamageSource $$1, - final ExplosionDamageCalculator $$2, final double $$3, final double $$4, final double $$5, final float $$6, - final boolean $$7, final Level.ExplosionInteraction $$8, final ParticleOptions $$9, final ParticleOptions $$10, - final Holder $$11, final CallbackInfo ci) { + private void tracker$afterExplodeCleanup( + final Entity $$0, final DamageSource $$1, final ExplosionDamageCalculator $$2, final double $$3, + final double $$4, final double $$5, final float $$6, final boolean $$7, final Level.ExplosionInteraction $$8, + final ParticleOptions $$9, final ParticleOptions $$10, final WeightedList $$11, + final Holder $$12, final CallbackInfo ci) { this.tracker$apiExplosion = null; } From 231ab0292ee0b55067da96e999da55ddd7e66e21 Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Mon, 1 Sep 2025 19:12:00 -0700 Subject: [PATCH 04/24] chore(minecraft): update to 25w34a Changes: - property name changes See: https://minecraft.wiki/w/Java_Edition_25w34a --- SpongeAPI | 2 +- gradle.properties | 2 +- .../data/provider/block/state/BlockStateDataProvider.java | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/SpongeAPI b/SpongeAPI index b121463d867..e11889e9800 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit b121463d867d4d0d65b04d77da285fca6beecd37 +Subproject commit e11889e9800cc3fdb0d4ab0dc7ec1e7b3fc109e2 diff --git a/gradle.properties b/gradle.properties index d81f4121e3f..f55f65bcbd3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.c mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json superClassChanges=common.superclasschange -minecraftVersion=25w33a +minecraftVersion=25w34a recommendedVersion=0-SNAPSHOT org.gradle.dependency.verification.console=verbose diff --git a/src/main/java/org/spongepowered/common/data/provider/block/state/BlockStateDataProvider.java b/src/main/java/org/spongepowered/common/data/provider/block/state/BlockStateDataProvider.java index d51022054f1..c6bd3fc18a1 100644 --- a/src/main/java/org/spongepowered/common/data/provider/block/state/BlockStateDataProvider.java +++ b/src/main/java/org/spongepowered/common/data/provider/block/state/BlockStateDataProvider.java @@ -49,7 +49,6 @@ public static void register(final DataProviderRegistrator registrator) { BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.AGE_4, BlockStateProperties.AGE_4); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.AGE_5, BlockStateProperties.AGE_5); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.AGE_7, BlockStateProperties.AGE_7); - BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.ALIGN_ITEMS_TO_BOTTOM, BlockStateProperties.ALIGN_ITEMS_TO_BOTTOM); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.ATTACHED, BlockStateProperties.ATTACHED); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.ATTACH_FACE, BlockStateProperties.ATTACH_FACE); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.AXIS, BlockStateProperties.AXIS); From b8beab8e86c41fbb7cb54ac6e30cc539f6eafca6 Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Mon, 1 Sep 2025 19:19:42 -0700 Subject: [PATCH 05/24] chore(minecraft): update to 25w35a Additions: - Add formerly server properties as game rules Breaking Change: - Rename CHAIN to IRON_CHAIN See: https://minecraft.wiki/w/Java_Edition_25w35a --- SpongeAPI | 2 +- .../generator/BlockStatePropertiesGenerator.java | 2 +- gradle.properties | 2 +- gradle/verification-metadata.xml | 16 ++++++++++++++++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/SpongeAPI b/SpongeAPI index e11889e9800..687ece5fafa 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit e11889e9800cc3fdb0d4ab0dc7ec1e7b3fc109e2 +Subproject commit 687ece5fafacbdb7f669c0b1118144279e4c760b diff --git a/generator/src/main/java/org/spongepowered/vanilla/generator/BlockStatePropertiesGenerator.java b/generator/src/main/java/org/spongepowered/vanilla/generator/BlockStatePropertiesGenerator.java index fbd3387f2e3..2e07feb0af8 100644 --- a/generator/src/main/java/org/spongepowered/vanilla/generator/BlockStatePropertiesGenerator.java +++ b/generator/src/main/java/org/spongepowered/vanilla/generator/BlockStatePropertiesGenerator.java @@ -155,7 +155,7 @@ static PropertyType ofProperty(final Property prop) { vanillaEnumTypeMapping.put(VaultState.class, BlockStatePropertiesGenerator.inDataTypePkg("VaultState")); vanillaEnumTypeMapping.put(CreakingHeartState.class, BlockStatePropertiesGenerator.inDataTypePkg("CreakingHeartState")); vanillaEnumTypeMapping.put(TestBlockMode.class, BlockStatePropertiesGenerator.inDataTypePkg("TestBlockMode")); - vanillaEnumTypeMapping.put(SideChainPart.class, BlockStatePropertiesGenerator.inDataTypePkg("SideChainPart")); + vanillaEnumTypeMapping.put(SideChainPart.class, BlockStatePropertiesGenerator.inDataTypePkg("SideChain")); vanillaEnumTypeMapping.put(CopperGolemStatueBlock.Pose.class, BlockStatePropertiesGenerator.inDataTypePkg("CopperGolemPose")); vanillaEnumTypeMapping.put(WeatheringCopper.WeatherState.class, BlockStatePropertiesGenerator.inDataTypePkg("CopperOxidation")); diff --git a/gradle.properties b/gradle.properties index f55f65bcbd3..c465ff07f25 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.c mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json superClassChanges=common.superclasschange -minecraftVersion=25w34a +minecraftVersion=25w35a recommendedVersion=0-SNAPSHOT org.gradle.dependency.verification.console=verbose diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 816b55f32ef..6236deaf226 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -1499,6 +1499,14 @@ + + + + + + + + @@ -2463,6 +2471,14 @@ + + + + + + + + From c7738c23210777b9b7675efa33e494705f6d21a0 Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Thu, 4 Sep 2025 17:49:22 -0700 Subject: [PATCH 06/24] chore(minecraft): update to 25w35a Updated entity, block, and profile-related API usages for library updates. See: https://minecraft.wiki/w/Java_Edition_25w35a --- .../world/level/BaseCommandBlockAccessor.java | 3 + .../entity/SkullBlockEntityAccessor.java | 1 - .../common/adventure/SpongeAdventure.java | 6 +- .../block/entity/CommandBlockData.java | 2 +- .../provider/block/entity/ConduitData.java | 2 +- .../data/provider/block/entity/SkullData.java | 16 ++++- .../provider/entity/AbstractHorseData.java | 2 +- .../data/provider/entity/AnimalData.java | 2 +- .../common/data/provider/entity/FoxData.java | 4 +- .../provider/entity/ServerPlayerData.java | 4 +- .../provider/entity/ShulkerBulletData.java | 2 +- .../common/data/provider/entity/TNTData.java | 2 +- .../data/provider/entity/TameableData.java | 2 +- .../item/stack/SkullItemStackData.java | 4 +- .../entity/living/human/HumanEntity.java | 33 +++++----- .../common/entity/player/SpongeUserData.java | 16 ++--- .../velocity/VelocityForwardingInfo.java | 2 +- .../network/packet/SpongePacketHandler.java | 4 +- .../network/status/SpongeStatusResponse.java | 2 +- .../common/profile/SpongeGameProfile.java | 12 ++-- .../profile/SpongeGameProfileManager.java | 2 +- .../profile/UncachedGameProfileProvider.java | 19 +++--- .../service/server/ban/SpongeIPBanList.java | 40 ++++++------ .../service/server/ban/SpongeUserBanList.java | 9 ++- .../permission/SpongePermissionService.java | 2 +- .../server/permission/UserSubject.java | 8 +-- .../server/whitelist/SpongeUserWhiteList.java | 11 ++-- .../common/user/SpongeUserManager.java | 10 +-- src/main/resources/common.accesswidener | 1 + .../server/MinecraftServerMixin_API.java | 14 +++-- .../server/level/ServerPlayerMixin_API.java | 3 +- .../entity/CommandBlockEntityMixin_API.java | 12 +++- .../chat/ComponentSerializationMixin.java | 2 +- .../chat/Component_SerializerMixin.java | 2 +- .../core/server/MinecraftServerMixin.java | 17 ++---- .../dedicated/DedicatedPlayerListMixin.java | 5 +- .../core/server/level/ServerPlayerMixin.java | 2 +- ...rConfigurationPacketListenerImplMixin.java | 6 +- .../ServerLoginPacketListenerImplMixin.java | 8 +-- .../server/players/GameProfileCacheMixin.java | 8 +-- .../core/server/players/PlayerListMixin.java | 9 +-- .../core/world/BaseCommandBlockMixin.java | 18 ++++-- .../vehicle/MinecartCommandBlockMixin.java | 3 +- .../block/entity/CommandBlockEntityMixin.java | 3 +- ...oginPacketListenerImplMixin_IpForward.java | 6 +- ...TamableAnimalMixin_Optimization_Owner.java | 2 +- .../DedicatedServerMixin_Tracker.java | 4 +- .../gui/widget/list/FilterableList.java | 61 +++++++++---------- .../gui/widget/list/PluginSelectionList.java | 23 ++++--- 49 files changed, 237 insertions(+), 194 deletions(-) diff --git a/src/accessors/java/org/spongepowered/common/accessor/world/level/BaseCommandBlockAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/world/level/BaseCommandBlockAccessor.java index d9db6bd2d9e..0ac83b2a8c0 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/world/level/BaseCommandBlockAccessor.java +++ b/src/accessors/java/org/spongepowered/common/accessor/world/level/BaseCommandBlockAccessor.java @@ -28,6 +28,7 @@ import net.minecraft.world.level.BaseCommandBlock; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; @Mixin(BaseCommandBlock.class) public interface BaseCommandBlockAccessor { @@ -40,4 +41,6 @@ public interface BaseCommandBlockAccessor { @Accessor("command") void accessor$command(final String command); + @Invoker("createSource") BaseCommandBlock.CloseableCommandBlockSource invoker$createSource(); + } diff --git a/src/accessors/java/org/spongepowered/common/accessor/world/level/block/entity/SkullBlockEntityAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/world/level/block/entity/SkullBlockEntityAccessor.java index e38e9af68a4..28f76ba8277 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/world/level/block/entity/SkullBlockEntityAccessor.java +++ b/src/accessors/java/org/spongepowered/common/accessor/world/level/block/entity/SkullBlockEntityAccessor.java @@ -35,5 +35,4 @@ public interface SkullBlockEntityAccessor { @Accessor("noteBlockSound") void accessor$noteBlockSound(final ResourceLocation location); @Accessor("noteBlockSound") ResourceLocation accessor$noteBlockSound(); - } diff --git a/src/main/java/org/spongepowered/common/adventure/SpongeAdventure.java b/src/main/java/org/spongepowered/common/adventure/SpongeAdventure.java index 2478f2342f3..65b58fc2651 100644 --- a/src/main/java/org/spongepowered/common/adventure/SpongeAdventure.java +++ b/src/main/java/org/spongepowered/common/adventure/SpongeAdventure.java @@ -75,15 +75,15 @@ import net.minecraft.network.chat.FontDescription; import net.minecraft.network.chat.HoverEvent.Action; import net.minecraft.network.chat.MutableComponent; -import net.minecraft.network.chat.contents.BlockDataSource; -import net.minecraft.network.chat.contents.EntityDataSource; import net.minecraft.network.chat.contents.KeybindContents; import net.minecraft.network.chat.contents.NbtContents; import net.minecraft.network.chat.contents.PlainTextContents; import net.minecraft.network.chat.contents.ScoreContents; import net.minecraft.network.chat.contents.SelectorContents; -import net.minecraft.network.chat.contents.StorageDataSource; import net.minecraft.network.chat.contents.TranslatableContents; +import net.minecraft.network.chat.contents.data.BlockDataSource; +import net.minecraft.network.chat.contents.data.EntityDataSource; +import net.minecraft.network.chat.contents.data.StorageDataSource; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerBossEvent; diff --git a/src/main/java/org/spongepowered/common/data/provider/block/entity/CommandBlockData.java b/src/main/java/org/spongepowered/common/data/provider/block/entity/CommandBlockData.java index 0d9edff6663..c5f787d725d 100644 --- a/src/main/java/org/spongepowered/common/data/provider/block/entity/CommandBlockData.java +++ b/src/main/java/org/spongepowered/common/data/provider/block/entity/CommandBlockData.java @@ -54,7 +54,7 @@ public static void register(final DataProviderRegistrator registrator) { .get(h -> h.getCommandBlock().getSuccessCount()) .set((h, v) -> ((BaseCommandBlockAccessor) h.getCommandBlock()).accessor$successCount(v)) .create(Keys.TRACKS_OUTPUT) - .get(h -> h.getCommandBlock().acceptsFailure()) + .get(h -> h.getCommandBlock().isTrackOutput()) .set((h, v) -> h.getCommandBlock().setTrackOutput(v)); } // @formatter:on diff --git a/src/main/java/org/spongepowered/common/data/provider/block/entity/ConduitData.java b/src/main/java/org/spongepowered/common/data/provider/block/entity/ConduitData.java index ac5b47ea0ac..e97bccf092a 100644 --- a/src/main/java/org/spongepowered/common/data/provider/block/entity/ConduitData.java +++ b/src/main/java/org/spongepowered/common/data/provider/block/entity/ConduitData.java @@ -66,7 +66,7 @@ public static void register(final DataProviderRegistrator registrator) { if (!(e instanceof LivingEntity le)) { return false; } - c.accessor$setDestroyTarget(new EntityReference<>(le)); + c.accessor$setDestroyTarget(EntityReference.of(le)); return true; }); //@formatter:on diff --git a/src/main/java/org/spongepowered/common/data/provider/block/entity/SkullData.java b/src/main/java/org/spongepowered/common/data/provider/block/entity/SkullData.java index a1736b556c5..813eb4c98af 100644 --- a/src/main/java/org/spongepowered/common/data/provider/block/entity/SkullData.java +++ b/src/main/java/org/spongepowered/common/data/provider/block/entity/SkullData.java @@ -24,6 +24,8 @@ */ package org.spongepowered.common.data.provider.block.entity; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.core.component.DataComponents; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.component.ResolvableProfile; import net.minecraft.world.level.block.entity.SkullBlockEntity; @@ -33,6 +35,8 @@ import org.spongepowered.common.data.provider.DataProviderRegistrator; import org.spongepowered.common.profile.SpongeGameProfile; +import java.util.UUID; + public final class SkullData { private SkullData() { @@ -45,12 +49,18 @@ public static void register(final DataProviderRegistrator registrator) { .create(Keys.GAME_PROFILE) .get(h -> { if (h.getOwnerProfile() != null) { - return SpongeGameProfile.of(h.getOwnerProfile().gameProfile()); + return SpongeGameProfile.of(h.getOwnerProfile().partialProfile()); } return null; }) - .set((h, v) -> h.setOwner(new ResolvableProfile(SpongeGameProfile.toMcProfile(v)))) - .delete(h -> h.setOwner(null)) + .set((h, v) -> { + h.applyComponents(h.components(), DataComponentPatch.builder() + .set(DataComponents.PROFILE, ResolvableProfile.createResolved(SpongeGameProfile.toMcProfile(v))) + .build()); + }) + .delete(h -> h.applyComponents(h.components(), DataComponentPatch.builder() + .set(DataComponents.PROFILE, ResolvableProfile.createUnresolved(new UUID(0, 0))) + .build())) .asMutable(SkullBlockEntityAccessor.class) .create(Keys.NOTE_BLOCK_SOUND) .get(h -> (ResourceKey) (Object) h.accessor$noteBlockSound()) diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/AbstractHorseData.java b/src/main/java/org/spongepowered/common/data/provider/entity/AbstractHorseData.java index 7c172711475..4576e7471f5 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/AbstractHorseData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/AbstractHorseData.java @@ -52,7 +52,7 @@ public static void register(final DataProviderRegistrator registrator) { return owner.getUUID(); }) .set((h, v) -> { - ((AbstractHorseAccessor) h).accessor$setOwner(new EntityReference<>(v)); + ((AbstractHorseAccessor) h).accessor$setOwner(EntityReference.of(v)); }) .delete(h -> { h.setOwner(null); diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/AnimalData.java b/src/main/java/org/spongepowered/common/data/provider/entity/AnimalData.java index 62866334dcc..d086ec3b5af 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/AnimalData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/AnimalData.java @@ -40,7 +40,7 @@ public static void register(final DataProviderRegistrator registrator) { .asMutable(AnimalAccessor.class) .create(Keys.BREEDER) .get(a -> a.accessor$loveCause().getUUID()) - .set(((animalAccessor, uuid) -> animalAccessor.accessor$loveCause(new EntityReference<>(uuid)))); + .set(((animalAccessor, uuid) -> animalAccessor.accessor$loveCause(EntityReference.of(uuid)))); } // @formatter:on } diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/FoxData.java b/src/main/java/org/spongepowered/common/data/provider/entity/FoxData.java index 7ee1a7afe41..1325ffea14b 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/FoxData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/FoxData.java @@ -44,7 +44,7 @@ public static void register(final DataProviderRegistrator registrator) { .asMutable(Fox.class) .create(Keys.FIRST_TRUSTED) .get(h -> h.getEntityData().get(FoxAccessor.accessor$DATA_TRUSTED_ID_0()).map(EntityReference::getUUID).orElse(null)) - .set((h, v) -> h.getEntityData().set(FoxAccessor.accessor$DATA_TRUSTED_ID_0(), Optional.ofNullable(v).map(EntityReference::new))) + .set((h, v) -> h.getEntityData().set(FoxAccessor.accessor$DATA_TRUSTED_ID_0(), Optional.ofNullable(v).map(EntityReference::of))) .create(Keys.FOX_TYPE) .get(h -> (FoxType) (Object) h.getVariant()) .set((h, v) -> ((FoxAccessor) h ).invoker$setVariant((Fox.Variant) (Object) v)) @@ -68,7 +68,7 @@ public static void register(final DataProviderRegistrator registrator) { .set((h, v) -> ((FoxAccessor) h).invoker$setSleeping(v)) .create(Keys.SECOND_TRUSTED) .get(h -> h.getEntityData().get(FoxAccessor.accessor$DATA_TRUSTED_ID_1()).map(EntityReference::getUUID).orElse(null)) - .set((h, v) -> h.getEntityData().set(FoxAccessor.accessor$DATA_TRUSTED_ID_1(), Optional.ofNullable(v).map(EntityReference::new))); + .set((h, v) -> h.getEntityData().set(FoxAccessor.accessor$DATA_TRUSTED_ID_1(), Optional.ofNullable(v).map(EntityReference::of))); } // @formatter:on } diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/ServerPlayerData.java b/src/main/java/org/spongepowered/common/data/provider/entity/ServerPlayerData.java index 5263916c19f..88bdbcfb6f4 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/ServerPlayerData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/ServerPlayerData.java @@ -74,14 +74,14 @@ public static void register(final DataProviderRegistrator registrator) { .get(h -> (GameMode) (Object) h.gameMode.getPreviousGameModeForPlayer()) .create(Keys.SKIN_PROFILE_PROPERTY) .get(h -> { - final Collection properties = h.getGameProfile().getProperties().get(ProfileProperty.TEXTURES); + final Collection properties = h.getGameProfile().properties().get(ProfileProperty.TEXTURES); if (properties.isEmpty()) { return null; } return new SpongeProfileProperty(properties.iterator().next()); }) .set((h ,v) -> { - h.getGameProfile().getProperties().replaceValues(ProfileProperty.TEXTURES, Collections.singletonList(((SpongeProfileProperty)v).asProperty())); + h.getGameProfile().properties().replaceValues(ProfileProperty.TEXTURES, Collections.singletonList(((SpongeProfileProperty)v).asProperty())); ServerPlayerData.resendProfile(h); }) .create(Keys.SPECTATOR_TARGET) diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/ShulkerBulletData.java b/src/main/java/org/spongepowered/common/data/provider/entity/ShulkerBulletData.java index 1f4fedc565a..63bdc810717 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/ShulkerBulletData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/ShulkerBulletData.java @@ -53,7 +53,7 @@ public static void register(final DataProviderRegistrator registrator) { } return (Entity) target.getEntity(((ShulkerBullet) h).level(), net.minecraft.world.entity.Entity.class); }) - .set((h, v) -> h.accessor$finalTarget(new EntityReference<>((net.minecraft.world.entity.Entity) v))); + .set((h, v) -> h.accessor$finalTarget(EntityReference.of((net.minecraft.world.entity.Entity) v))); } // @formatter:on } diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/TNTData.java b/src/main/java/org/spongepowered/common/data/provider/entity/TNTData.java index 3136f6d8903..157e4f912ee 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/TNTData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/TNTData.java @@ -44,7 +44,7 @@ public static void register(final DataProviderRegistrator registrator) { .asMutable(PrimedTnt.class) .create(Keys.DETONATOR) .get(h -> (Living) h.getOwner()) - .set((h, v) -> ((PrimedTntAccessor) h).accessor$owner(new EntityReference<>((LivingEntity) v))) + .set((h, v) -> ((PrimedTntAccessor) h).accessor$owner(EntityReference.of((LivingEntity) v))) .create(Keys.BLOCK_STATE) .get(h -> (BlockState) h.getBlockState()) .set((h, v) -> h.setBlockState((net.minecraft.world.level.block.state.BlockState) v)); diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/TameableData.java b/src/main/java/org/spongepowered/common/data/provider/entity/TameableData.java index 3216f124da9..e245c0b2f83 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/TameableData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/TameableData.java @@ -52,7 +52,7 @@ public static void register(final DataProviderRegistrator registrator) { return t.getOwnerReference().getUUID(); }) .set((h, v) -> { - h.setOwnerReference(new EntityReference<>(v)); + h.setOwnerReference(EntityReference.of(v)); h.setTame(v != null, true); }); } diff --git a/src/main/java/org/spongepowered/common/data/provider/item/stack/SkullItemStackData.java b/src/main/java/org/spongepowered/common/data/provider/item/stack/SkullItemStackData.java index 77af4878013..78059b24ce8 100644 --- a/src/main/java/org/spongepowered/common/data/provider/item/stack/SkullItemStackData.java +++ b/src/main/java/org/spongepowered/common/data/provider/item/stack/SkullItemStackData.java @@ -46,11 +46,11 @@ public static void register(final DataProviderRegistrator registrator) { .create(Keys.GAME_PROFILE) .get(h -> { final ResolvableProfile resolvableProfile = h.get(DataComponents.PROFILE); - return resolvableProfile == null ? null : SpongeGameProfile.of(resolvableProfile.gameProfile()); + return resolvableProfile == null ? null : SpongeGameProfile.of(resolvableProfile.partialProfile()); }) .set((h, v) -> { final com.mojang.authlib.GameProfile mcProfile = SpongeGameProfile.toMcProfile(v); - h.set(DataComponents.PROFILE, new ResolvableProfile(mcProfile)); + h.set(DataComponents.PROFILE, ResolvableProfile.createResolved(mcProfile)); }) .delete(h -> h.remove(DataComponents.PROFILE)) .supports(h -> h.getItem() instanceof PlayerHeadItem) diff --git a/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java b/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java index 28ee38978fc..c09b7f5e3a2 100644 --- a/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java +++ b/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java @@ -123,7 +123,7 @@ public static AttributeSupplier createAttributes() { public HumanEntity(final EntityType type, final Level world) { super(type, world); - this.fakeProfile = new ResolvableProfile(new GameProfile(this.uuid, "")); + this.fakeProfile = ResolvableProfile.createUnresolved(this.uuid); this.setCanPickUpLoot(true); this.entityData.set(PlayerAccessor.accessor$DATA_PLAYER_MODE_CUSTOMISATION(), Constants.Sponge.Entity.Human.PLAYER_MODEL_FLAG_ALL); } @@ -196,7 +196,7 @@ public void readAdditionalSaveData(final ValueInput tag) { tag.read("profile", ResolvableProfile.CODEC) .ifPresent(profile -> { this.fakeProfile = profile; - this.setUUID(this.fakeProfile.id().get()); + this.setUUID(this.fakeProfile.partialProfile().id()); }); } @@ -307,26 +307,27 @@ protected HoverEvent createHoverEvent() { private void setProfileName(final net.minecraft.network.chat.@Nullable Component newName) { final Optional optName = Optional.ofNullable(newName).map(net.minecraft.network.chat.Component::getString); - this.fakeProfile = new ResolvableProfile(optName, this.fakeProfile.id(), this.fakeProfile.properties()); + final var profile = new GameProfile(this.fakeProfile.partialProfile().id(), optName.orElse(this.fakeProfile.name().orElse("")), this.fakeProfile.partialProfile().properties()); + this.fakeProfile = ResolvableProfile.createResolved(profile); } public boolean getOrLoadSkin(final UUID minecraftAccount) { final var server = SpongeCommon.server(); - final @Nullable GameProfile profile = server.nameToIdCache().get(minecraftAccount).flatMap(name -> - server.getProfileRepository().findProfileByName(name.name()) + final @Nullable GameProfile profile = server.services().nameToIdCache().get(minecraftAccount).flatMap(name -> + server.services().profileResolver().fetchByName(name.name()) ).orElseGet(() -> { - final @Nullable ProfileResult result = server.getSessionService().fetchProfile(minecraftAccount, true); + final @Nullable ProfileResult result = server.services().sessionService().fetchProfile(minecraftAccount, true); if (result == null) { return null; } - server.nameToIdCache().add(new NameAndId(result.profile())); + server.services().nameToIdCache().add(new NameAndId(result.profile())); return result.profile(); }); if (profile == null) { return false; } - this.fakeProfile.properties().replaceValues(ProfileProperty.TEXTURES, profile.getProperties().get(ProfileProperty.TEXTURES)); + this.fakeProfile.partialProfile().properties().replaceValues(ProfileProperty.TEXTURES, profile.properties().get(ProfileProperty.TEXTURES)); if (this.isAliveAndInWorld()) { this.respawnOnClient(); } @@ -337,15 +338,15 @@ public boolean getOrLoadSkin(final UUID minecraftAccount) { public boolean getOrLoadSkin(final String minecraftAccount) { Objects.requireNonNull(minecraftAccount); final var server = SpongeCommon.server(); - final @Nullable GameProfile profile = server.nameToIdCache().get(minecraftAccount).flatMap(name -> - server.getProfileRepository().findProfileByName(name.name()) + final @Nullable GameProfile profile = server.services().nameToIdCache().get(minecraftAccount).flatMap(name -> + server.services().profileResolver().fetchByName(name.name()) ).orElse(null); if (profile == null) { return false; } - this.fakeProfile.properties().clear(); - this.fakeProfile.properties().putAll(profile.getProperties()); + this.fakeProfile.partialProfile().properties().clear(); + this.fakeProfile.partialProfile().properties().putAll(profile.properties()); if (this.isAliveAndInWorld()) { this.respawnOnClient(); } @@ -368,7 +369,7 @@ public void removeFromTabListDelayed(final @Nullable ServerPlayer player, final } public SpongeProfileProperty getSkinProperty() { - final Collection properties = this.fakeProfile.properties().get(ProfileProperty.TEXTURES); + final Collection properties = this.fakeProfile.partialProfile().properties().get(ProfileProperty.TEXTURES); if (properties.isEmpty()) { return null; } @@ -376,7 +377,7 @@ public SpongeProfileProperty getSkinProperty() { } public void setSkinProperty(final ProfileProperty property) { - this.fakeProfile.properties() + this.fakeProfile.partialProfile().properties() .replaceValues( ProfileProperty.TEXTURES, Collections.singletonList(((SpongeProfileProperty) property).asProperty())); @@ -406,7 +407,7 @@ private void respawnOnClient() { * @return Whether it can be removed with 0 ticks delay */ public boolean canRemoveFromListImmediately() { - return !this.fakeProfile.properties().containsKey(ProfileProperty.TEXTURES); + return !this.fakeProfile.partialProfile().properties().containsKey(ProfileProperty.TEXTURES); } /** @@ -432,7 +433,7 @@ public ClientboundPlayerInfoUpdatePacket createPlayerListPacket(final EnumSet player() { - return Optional.ofNullable((ServerPlayer) SpongeCommon.server().getPlayerList().getPlayer(this.profile.getId())); + return Optional.ofNullable((ServerPlayer) SpongeCommon.server().getPlayerList().getPlayer(this.profile.id())); } @Override @@ -601,12 +601,12 @@ public boolean equals(final Object obj) { return false; } final SpongeUserData other = (SpongeUserData) obj; - return this.profile.getId().equals(other.profile.getId()); + return this.profile.id().equals(other.profile.id()); } @Override public int hashCode() { - return this.profile.getId().hashCode(); + return this.profile.id().hashCode(); } @Override diff --git a/src/main/java/org/spongepowered/common/ipforward/velocity/VelocityForwardingInfo.java b/src/main/java/org/spongepowered/common/ipforward/velocity/VelocityForwardingInfo.java index 24e61dbee81..c79a5096e42 100644 --- a/src/main/java/org/spongepowered/common/ipforward/velocity/VelocityForwardingInfo.java +++ b/src/main/java/org/spongepowered/common/ipforward/velocity/VelocityForwardingInfo.java @@ -146,7 +146,7 @@ private static void readProperties(final ChannelBuf buf, final GameProfile profi final String name = buf.readString(); final String value = buf.readString(); final String signature = buf.readBoolean() ? buf.readString() : null; - profile.getProperties().put(name, new Property(name, value, signature)); + profile.properties().put(name, new Property(name, value, signature)); } } } diff --git a/src/main/java/org/spongepowered/common/network/packet/SpongePacketHandler.java b/src/main/java/org/spongepowered/common/network/packet/SpongePacketHandler.java index d8798e4b23f..98aa8a2a3c9 100644 --- a/src/main/java/org/spongepowered/common/network/packet/SpongePacketHandler.java +++ b/src/main/java/org/spongepowered/common/network/packet/SpongePacketHandler.java @@ -110,10 +110,10 @@ private static TrackerDataResponsePacket createTrackerDataResponse( final Optional owner, final Optional notifier ) { - final String ownerName = owner.flatMap(SpongeCommon.server().nameToIdCache()::get) + final String ownerName = owner.flatMap(SpongeCommon.server().services().nameToIdCache()::get) .map(NameAndId::name) .orElse(""); - final String notifierName = notifier.flatMap(SpongeCommon.server().nameToIdCache()::get) + final String notifierName = notifier.flatMap(SpongeCommon.server().services().nameToIdCache()::get) .map(NameAndId::name) .orElse(""); return new TrackerDataResponsePacket(ownerName, notifierName); diff --git a/src/main/java/org/spongepowered/common/network/status/SpongeStatusResponse.java b/src/main/java/org/spongepowered/common/network/status/SpongeStatusResponse.java index 043383b8615..93fecddd0e0 100644 --- a/src/main/java/org/spongepowered/common/network/status/SpongeStatusResponse.java +++ b/src/main/java/org/spongepowered/common/network/status/SpongeStatusResponse.java @@ -121,7 +121,7 @@ public ServerStatus.Players toVanilla() { // Make sure profiles are sent with non-null UUIDs and names because everything else // will make the response invalid on the client. Some plugins use empty UUIDs to create // custom lines in the player list that do not refer to a specific player. - .map(SpongeGameProfile::toMcProfile) + .map(SpongeGameProfile::toNameAndId) .toList()); } } diff --git a/src/main/java/org/spongepowered/common/profile/SpongeGameProfile.java b/src/main/java/org/spongepowered/common/profile/SpongeGameProfile.java index 7c75e137602..49264d46148 100644 --- a/src/main/java/org/spongepowered/common/profile/SpongeGameProfile.java +++ b/src/main/java/org/spongepowered/common/profile/SpongeGameProfile.java @@ -62,9 +62,9 @@ public static SpongeGameProfile of(NameAndId mcProfile) { } public static SpongeGameProfile of(final com.mojang.authlib.GameProfile mcProfile) { - final UUID uniqueId = mcProfile.getId(); - final String name = mcProfile.getName().isEmpty() ? null : mcProfile.getName(); - final List properties = mcProfile.getProperties().values().stream() + final UUID uniqueId = mcProfile.id(); + final String name = mcProfile.name().isEmpty() ? null : mcProfile.name(); + final List properties = mcProfile.properties().values().stream() .map(SpongeProfileProperty::new) .collect(Collectors.toList()); return new SpongeGameProfile(uniqueId, name, properties); @@ -76,8 +76,8 @@ public static SpongeGameProfile basicOf(final NameAndId mcProfile) { } public static SpongeGameProfile basicOf(final com.mojang.authlib.GameProfile mcProfile) { - final UUID uniqueId = mcProfile.getId(); - final String name = mcProfile.getName().isEmpty() ? null : mcProfile.getName(); + final UUID uniqueId = mcProfile.id(); + final String name = mcProfile.name().isEmpty() ? null : mcProfile.name(); return new SpongeGameProfile(uniqueId, name); } @@ -150,7 +150,7 @@ public com.mojang.authlib.GameProfile toMcProfile() { final String name = (this.name == null) ? "" : this.name; final com.mojang.authlib.GameProfile mcProfile = new com.mojang.authlib.GameProfile(uniqueId, name); for (final SpongeProfileProperty property : this.properties) { - mcProfile.getProperties().put(property.name(), property.asProperty()); + mcProfile.properties().put(property.name(), property.asProperty()); } return mcProfile; } diff --git a/src/main/java/org/spongepowered/common/profile/SpongeGameProfileManager.java b/src/main/java/org/spongepowered/common/profile/SpongeGameProfileManager.java index 49fbc37b122..8bd5b7c5846 100644 --- a/src/main/java/org/spongepowered/common/profile/SpongeGameProfileManager.java +++ b/src/main/java/org/spongepowered/common/profile/SpongeGameProfileManager.java @@ -67,7 +67,7 @@ public final class SpongeGameProfileManager implements GameProfileManager { public SpongeGameProfileManager(final Server server) { this.usernameCache = ((SpongeServer) server).getUsernameCache(); - this.cache = (GameProfileCacheBridge) ((MinecraftServer) server).nameToIdCache(); + this.cache = (GameProfileCacheBridge) ((MinecraftServer) server).services().nameToIdCache(); this.gameLookupExecutorService = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder() .setNameFormat("Sponge - Async User Lookup Thread").build()); } diff --git a/src/main/java/org/spongepowered/common/profile/UncachedGameProfileProvider.java b/src/main/java/org/spongepowered/common/profile/UncachedGameProfileProvider.java index a682289cdf0..31d6c3770b3 100644 --- a/src/main/java/org/spongepowered/common/profile/UncachedGameProfileProvider.java +++ b/src/main/java/org/spongepowered/common/profile/UncachedGameProfileProvider.java @@ -36,6 +36,7 @@ import com.mojang.authlib.ProfileLookupCallback; import com.mojang.authlib.yggdrasil.ProfileResult; import com.mojang.util.UndashedUuid; +import net.minecraft.server.players.NameAndId; import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.core.util.Throwables; import org.checkerframework.checker.nullness.qual.Nullable; @@ -92,7 +93,7 @@ private void submit(final Runnable runnable) { final com.mojang.authlib.GameProfile mcProfile; if (SpongeGameProfileManager.canLookup(uniqueId)) { // only attempt to resolve profiles for online mode clients - ProfileResult result = SpongeCommon.server().getSessionService().fetchProfile(uniqueId, true); + ProfileResult result = SpongeCommon.server().services().sessionService().fetchProfile(uniqueId, true); if (result != null) { mcProfile = result.profile(); } else { @@ -105,7 +106,7 @@ private void submit(final Runnable runnable) { return null; } final CachedProfile cachedProfile = new CachedProfile(SpongeGameProfile.of(mcProfile)); - this.profileByNameCache.put(mcProfile.getName().toLowerCase(Locale.ROOT), cachedProfile); + this.profileByNameCache.put(mcProfile.name().toLowerCase(Locale.ROOT), cachedProfile); return cachedProfile; }); } @@ -185,7 +186,7 @@ public CompletableFuture basicProfile(final String name, final @Nul }); } final CompletableFuture result = new CompletableFuture<>(); - this.submit(() -> SpongeCommon.server().getProfileRepository().findProfilesByNames(new String[]{name}, + this.submit(() -> SpongeCommon.server().services().profileRepository().findProfilesByNames(new String[]{name}, new SingleProfileLookupCallback(result))); return result; } @@ -213,7 +214,7 @@ public CompletableFuture> basicProfiles(final Iterable< } final List nameList = Lists.newArrayList(names); final String[] namesArray = nameList.toArray(new String[0]); - this.submit(() -> SpongeCommon.server().getProfileRepository().findProfilesByNames(namesArray, + this.submit(() -> SpongeCommon.server().services().profileRepository().findProfilesByNames(namesArray, new MapProfileLookupCallback(result, nameList))); return result; } @@ -288,8 +289,8 @@ private SingleProfileLookupCallback(final CompletableFuture result) } @Override - public void onProfileLookupSucceeded(final com.mojang.authlib.GameProfile profile) { - this.result.complete(SpongeGameProfile.of(profile)); + public void onProfileLookupSucceeded(String profileName, UUID profileId) { + this.result.complete(SpongeGameProfile.of(new NameAndId(profileId, profileName))); } @Override @@ -321,11 +322,11 @@ public void complete() { } @Override - public void onProfileLookupSucceeded(final com.mojang.authlib.GameProfile profile) { + public void onProfileLookupSucceeded(String profileName, UUID profileId) { String originalName = null; while (originalName == null && !this.nameQueue.isEmpty()) { final String name = this.nameQueue.remove(0); - if (name.equalsIgnoreCase(profile.getName())) { + if (name.equalsIgnoreCase(profileName)) { originalName = name; } } @@ -333,7 +334,7 @@ public void onProfileLookupSucceeded(final com.mojang.authlib.GameProfile profil throw new IllegalStateException(); } if (this.resultMap != null) { - this.resultMap.put(originalName, SpongeGameProfile.of(profile)); + this.resultMap.put(originalName, SpongeGameProfile.of(new NameAndId(profileId, profileName))); } } diff --git a/src/main/java/org/spongepowered/common/service/server/ban/SpongeIPBanList.java b/src/main/java/org/spongepowered/common/service/server/ban/SpongeIPBanList.java index 6ee8716ff4a..32cb8edf41c 100644 --- a/src/main/java/org/spongepowered/common/service/server/ban/SpongeIPBanList.java +++ b/src/main/java/org/spongepowered/common/service/server/ban/SpongeIPBanList.java @@ -27,6 +27,7 @@ import static org.spongepowered.common.util.NetworkUtil.LOCAL_ADDRESS; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import net.minecraft.server.notifications.EmptyNotificationService; import net.minecraft.server.players.IpBanList; import net.minecraft.server.players.IpBanListEntry; import org.checkerframework.checker.nullness.qual.Nullable; @@ -44,6 +45,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Optional; /** * Redirects all calls to the {@link BanService}. @@ -51,7 +53,7 @@ public final class SpongeIPBanList extends IpBanList { public SpongeIPBanList(final File file) { - super(file); + super(file, new EmptyNotificationService()); } @Override @@ -75,31 +77,31 @@ protected boolean contains(final String entry) { try { return Sponge.server().serviceProvider().banService().find(InetAddress.getByName(obj)).join() - .map(ban -> { - if (ban instanceof IpBanListEntry) { - return (IpBanListEntry) ban; - } - final LegacyComponentSerializer lcs = LegacyComponentSerializer.legacySection(); - return new IpBanListEntry(BanUtil.addressToBanCompatibleString(ban.address()), - Date.from(ban.creationDate()), - ban.banSource().map(lcs::serialize).orElse(null), - ban.expirationDate().map(Date::from).orElse(null), - ban.reason().map(lcs::serialize).orElse(null)); - }) - .orElse(null); + .map(ban -> { + if (ban instanceof IpBanListEntry) { + return (IpBanListEntry) ban; + } + final LegacyComponentSerializer lcs = LegacyComponentSerializer.legacySection(); + return new IpBanListEntry(BanUtil.addressToBanCompatibleString(ban.address()), + Date.from(ban.creationDate()), + ban.banSource().map(lcs::serialize).orElse(null), + ban.expirationDate().map(Date::from).orElse(null), + ban.reason().map(lcs::serialize).orElse(null)); + }) + .orElse(null); } catch (final UnknownHostException e) { throw new IllegalArgumentException("Error parsing Ban IP address!", e); } } @Override - public void remove(final String entry) { + public boolean remove(final String entry) { if (entry.equals(LOCAL_ADDRESS)) { // Check for single player - return; + return false; } try { - Sponge.server().serviceProvider().banService().pardon(InetAddress.getByName(entry)).join(); + return Sponge.server().serviceProvider().banService().pardon(InetAddress.getByName(entry)).join(); } catch (final UnknownHostException e) { throw new IllegalArgumentException("Error parsing Ban IP address!", e); } @@ -115,8 +117,8 @@ public String[] getUserList() { } @Override - public void add(final IpBanListEntry entry) { - Sponge.server().serviceProvider().banService().add((Ban) entry).join(); + public boolean add(final IpBanListEntry entry) { + return Sponge.server().serviceProvider().banService().add((Ban) entry).thenApply(Optional::isPresent).join(); } @Override @@ -127,7 +129,7 @@ public boolean isEmpty() { /** * @author Minecrell - August 22nd, 2016 * @reason Use InetSocketAddress#getHostString() where possible (instead of - * inspecting SocketAddress#toString()) to support IPv6 addresses + * inspecting SocketAddress#toString()) to support IPv6 addresses */ @Override public String getIpFromAddress(final SocketAddress address) { diff --git a/src/main/java/org/spongepowered/common/service/server/ban/SpongeUserBanList.java b/src/main/java/org/spongepowered/common/service/server/ban/SpongeUserBanList.java index 35ca1c9575a..e020e63cef9 100644 --- a/src/main/java/org/spongepowered/common/service/server/ban/SpongeUserBanList.java +++ b/src/main/java/org/spongepowered/common/service/server/ban/SpongeUserBanList.java @@ -25,6 +25,7 @@ package org.spongepowered.common.service.server.ban; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import net.minecraft.server.notifications.EmptyNotificationService; import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.UserBanList; import net.minecraft.server.players.UserBanListEntry; @@ -48,7 +49,7 @@ public class SpongeUserBanList extends UserBanList { public SpongeUserBanList(final File file) { - super(file); + super(file, new EmptyNotificationService()); } @Override @@ -84,9 +85,10 @@ public String[] getUserList() { } @Override - public void add(final UserBanListEntry entry) { + public boolean add(final UserBanListEntry entry) { final CompletableFuture> completableFuture = Sponge.server().serviceProvider().banService().add((Ban) entry); ((MinecraftServerBridge) SpongeCommon.server()).bridge$spongeMainThreadExecutor().managedBlock(completableFuture::isDone); + return true; } @Override @@ -95,9 +97,10 @@ public boolean isEmpty() { } @Override - public void remove(final NameAndId entry) { + public boolean remove(final NameAndId entry) { final CompletableFuture completableFuture = Sponge.server().serviceProvider().banService().pardon(SpongeGameProfile.of(entry)); ((MinecraftServerBridge) SpongeCommon.server()).bridge$spongeMainThreadExecutor().managedBlock(completableFuture::isDone); + return true; } } diff --git a/src/main/java/org/spongepowered/common/service/server/permission/SpongePermissionService.java b/src/main/java/org/spongepowered/common/service/server/permission/SpongePermissionService.java index 819721fc656..f895f30c097 100644 --- a/src/main/java/org/spongepowered/common/service/server/permission/SpongePermissionService.java +++ b/src/main/java/org/spongepowered/common/service/server/permission/SpongePermissionService.java @@ -100,7 +100,7 @@ static ServerOpList getOps() { } static int getServerOpLevel() { - return SpongeCommon.server().getOperatorUserPermissionLevel(); + return SpongeCommon.server().operatorUserPermissionLevel(); } public Subject getGroupForOpLevel(final int level) { diff --git a/src/main/java/org/spongepowered/common/service/server/permission/UserSubject.java b/src/main/java/org/spongepowered/common/service/server/permission/UserSubject.java index df90e34cd52..6dc24539697 100644 --- a/src/main/java/org/spongepowered/common/service/server/permission/UserSubject.java +++ b/src/main/java/org/spongepowered/common/service/server/permission/UserSubject.java @@ -81,12 +81,12 @@ public void setParent(final SubjectReference parent) { @Override public String identifier() { - return this.player.getId().toString(); + return this.player.id().toString(); } @Override public Optional friendlyIdentifier() { - final String name = this.player.getName(); + final String name = this.player.name(); return name.isEmpty() ? Optional.empty() : Optional.of(name); } @@ -96,7 +96,7 @@ public Optional associatedObject() { return Optional.empty(); } - return Sponge.server().player(this.player.getId()); + return Sponge.server().player(this.player.id()); } int getOpLevel() { @@ -106,7 +106,7 @@ int getOpLevel() { final ServerOpListEntry entry = SpongePermissionService.getOps().get(this.nameAndId); if (entry == null) { // Take care of singleplayer commands -- unless an op level is specified, this player follows global rules - return SpongeCommon.server().getPlayerList().isOp(this.nameAndId) ? SpongeCommon.server().getOperatorUserPermissionLevel() : 0; + return SpongeCommon.server().getPlayerList().isOp(this.nameAndId) ? SpongeCommon.server().operatorUserPermissionLevel() : 0; } else { return entry.getLevel(); } diff --git a/src/main/java/org/spongepowered/common/service/server/whitelist/SpongeUserWhiteList.java b/src/main/java/org/spongepowered/common/service/server/whitelist/SpongeUserWhiteList.java index 694aacc02c8..760b7d297dc 100644 --- a/src/main/java/org/spongepowered/common/service/server/whitelist/SpongeUserWhiteList.java +++ b/src/main/java/org/spongepowered/common/service/server/whitelist/SpongeUserWhiteList.java @@ -24,6 +24,7 @@ */ package org.spongepowered.common.service.server.whitelist; +import net.minecraft.server.notifications.EmptyNotificationService; import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.UserWhiteList; import net.minecraft.server.players.UserWhiteListEntry; @@ -43,7 +44,7 @@ public class SpongeUserWhiteList extends UserWhiteList { public SpongeUserWhiteList(final File file) { - super(file); + super(file, new EmptyNotificationService()); } @Override @@ -62,13 +63,13 @@ public String[] getUserList() { @SuppressWarnings("unchecked") @Override - public void add(final UserWhiteListEntry entry) { - Sponge.server().serviceProvider().whitelistService().addProfile(SpongeGameProfile.of(((StoredUserEntryAccessor) entry).accessor$user())).join(); + public boolean add(final UserWhiteListEntry entry) { + return Sponge.server().serviceProvider().whitelistService().addProfile(SpongeGameProfile.of(((StoredUserEntryAccessor) entry).accessor$user())).join(); } @Override - public void remove(final NameAndId entry) { - Sponge.server().serviceProvider().whitelistService().removeProfile(SpongeGameProfile.of(entry)).join(); + public boolean remove(final NameAndId entry) { + return Sponge.server().serviceProvider().whitelistService().removeProfile(SpongeGameProfile.of(entry)).join(); } @Override diff --git a/src/main/java/org/spongepowered/common/user/SpongeUserManager.java b/src/main/java/org/spongepowered/common/user/SpongeUserManager.java index 08445d2b1ff..09a24729dd9 100644 --- a/src/main/java/org/spongepowered/common/user/SpongeUserManager.java +++ b/src/main/java/org/spongepowered/common/user/SpongeUserManager.java @@ -112,7 +112,7 @@ public CompletableFuture loadOrCreate(final UUID uuid) { return CompletableFuture.completedFuture(null); } return CompletableFuture.supplyAsync(() -> { - final com.mojang.authlib.GameProfile profile = this.server.nameToIdCache().get(uuidToUse) + final com.mojang.authlib.GameProfile profile = this.server.services().nameToIdCache().get(uuidToUse) .map(nameAndId -> new com.mojang.authlib.GameProfile(nameAndId.id(), nameAndId.name())) .orElseGet(() -> new com.mojang.authlib.GameProfile(uuidToUse, "")); try { @@ -135,7 +135,7 @@ public CompletableFuture> load(final String lastKnownName) { .map(SpongeGameProfile::toMcProfile) .orElse(null); if (mcProfile != null) { - return this.load(mcProfile.getId()); + return this.load(mcProfile.id()); } return CompletableFuture.completedFuture(Optional.empty()); } @@ -234,7 +234,7 @@ private UUID ensureNonEmptyUUID(final UUID uuid) { // public void handlePlayerLogin(final com.mojang.authlib.GameProfile mcProfile) throws IOException { - final @Nullable SpongeUserData currentUser = this.userCache.getIfPresent(mcProfile.getId()); + final @Nullable SpongeUserData currentUser = this.userCache.getIfPresent(mcProfile.id()); if (currentUser != null) { // If currentUser have this then we know that the user has changed. if (this.dirtyUsers.contains(currentUser)) { @@ -247,8 +247,8 @@ public void handlePlayerLogin(final com.mojang.authlib.GameProfile mcProfile) th private void createUser(final com.mojang.authlib.GameProfile profile) throws IOException { final @Nullable SpongeUserData user = SpongeUserData.create(profile); - this.userCache.put(profile.getId(), user); - this.userFileCache.userCreated(profile.getId()); + this.userCache.put(profile.id(), user); + this.userFileCache.userCreated(profile.id()); } public void markDirty(final SpongeUserData user) { diff --git a/src/main/resources/common.accesswidener b/src/main/resources/common.accesswidener index 9003fe0764a..ab0f0901043 100644 --- a/src/main/resources/common.accesswidener +++ b/src/main/resources/common.accesswidener @@ -19,3 +19,4 @@ accessible class net/minecraft/network/protocol/game/ServerboundInteractPacket$A accessible class net/minecraft/world/entity/monster/SpellcasterIllager$IllagerSpell accessible class net/minecraft/world/level/biome/Biome$ClimateSettings accessible class net/minecraft/core/MappedRegistry$TagSet +accessible class net/minecraft/world/level/BaseCommandBlock$CloseableCommandBlockSource \ No newline at end of file diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/MinecraftServerMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/MinecraftServerMixin_API.java index 6ce7054e45e..b56db122407 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/MinecraftServerMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/MinecraftServerMixin_API.java @@ -41,6 +41,7 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.server.players.PlayerList; +import net.minecraft.world.level.GameRules; import net.minecraft.world.level.levelgen.WorldDimensions; import net.minecraft.world.level.levelgen.WorldGenSettings; import net.minecraft.world.level.storage.LevelResource; @@ -122,12 +123,11 @@ public abstract class MinecraftServerMixin_API implements SpongeServer, SpongeRe @Shadow public abstract String shadow$getMotd(); @Shadow public abstract int shadow$getTickCount(); @Shadow public abstract void shadow$halt(boolean p_71263_1_); - @Shadow public abstract int shadow$getPlayerIdleTimeout(); @Shadow public abstract void shadow$setPlayerIdleTimeout(int p_143006_1_); @Shadow public abstract boolean shadow$isHardcore(); @Shadow public abstract boolean shadow$isPvpAllowed(); @Shadow public abstract boolean shadow$isCommandBlockEnabled(); - @Shadow public abstract boolean shadow$isSpawningMonsters(); + @Shadow protected abstract boolean shadow$isSpawningMonsters(); @Shadow public abstract Commands shadow$getCommands(); @Shadow public abstract PackRepository shadow$getPackRepository(); @Shadow public abstract net.minecraft.server.packs.resources.ResourceManager shadow$getResourceManager(); @@ -143,6 +143,10 @@ public abstract class MinecraftServerMixin_API implements SpongeServer, SpongeRe @Shadow public abstract boolean isSingleplayer(); + @Shadow public abstract void shadow$setUsingWhitelist(boolean $$0); + + @Shadow public abstract int shadow$playerIdleTimeout(); + private Iterable audiences; private ServerScheduler api$scheduler; private SpongeWorldManager api$worldManager; @@ -217,7 +221,7 @@ public boolean isWhitelistEnabled() { @Override public void setHasWhitelist(final boolean enabled) { - this.shadow$getPlayerList().setUsingWhiteList(enabled); + this.shadow$setUsingWhitelist(enabled); } @Override @@ -270,7 +274,7 @@ public boolean isAnimalSpawnsEnabled() { */ @Override public boolean isMultiWorldEnabled() { - return this.isSingleplayer() || ((Object) this instanceof DedicatedServer ds) && ds.getProperties().allowNether; + return this.isSingleplayer() || ((Object) this instanceof DedicatedServer ds) && ds.getGameRules().getBoolean(GameRules.RULE_ALLOW_NETHER); } @Override @@ -419,7 +423,7 @@ public Optional serverScoreboard() { @Intrinsic public int server$playerIdleTimeout() { - return this.shadow$getPlayerIdleTimeout(); + return this.shadow$playerIdleTimeout(); } @Intrinsic diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/level/ServerPlayerMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/level/ServerPlayerMixin_API.java index 926dea4c5ef..07fa31df462 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/level/ServerPlayerMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/server/level/ServerPlayerMixin_API.java @@ -326,7 +326,7 @@ public Optional setWorldBorder(final @Nullable WorldBorder border) synchronized (this) { if (this.api$pointers == null) { this.api$pointers = pointers = Pointers.builder() - .withDynamic(Identity.NAME, () -> ((net.minecraft.server.level.ServerPlayer) (Object) this).getGameProfile().getName()) + .withDynamic(Identity.NAME, () -> ((net.minecraft.server.level.ServerPlayer) (Object) this).getGameProfile().name()) .withDynamic(Identity.DISPLAY_NAME, () -> this.displayName().get()) .withDynamic(Identity.UUID, ((Entity) (Object) this)::getUUID) .withDynamic(Identity.LOCALE, this::locale) @@ -342,6 +342,7 @@ public Optional setWorldBorder(final @Nullable WorldBorder border) @Override @Deprecated + @SuppressWarnings("deprecation") public void sendMessage(final Identity identity, final Component message, final MessageType type) { if (this.impl$isFake) { return; 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 119aece2369..367285e8f68 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 @@ -36,6 +36,7 @@ import org.spongepowered.api.data.value.Value; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.common.accessor.world.level.BaseCommandBlockAccessor; import org.spongepowered.common.adventure.SpongeAdventure; import org.spongepowered.common.util.Constants; @@ -64,8 +65,8 @@ public DataContainer toContainer() { container.set(Constants.TileEntity.CommandBlock.STORED_COMMAND, this.shadow$getCommandBlock().getCommand()); container.set(Constants.TileEntity.CommandBlock.SUCCESS_COUNT, this.shadow$getCommandBlock().getSuccessCount()); container.set(Constants.TileEntity.CUSTOM_NAME, this.shadow$getCommandBlock().getName()); - container.set(Constants.TileEntity.CommandBlock.DOES_TRACK_OUTPUT, this.shadow$getCommandBlock().shouldInformAdmins()); - if (this.shadow$getCommandBlock().shouldInformAdmins()) { + container.set(Constants.TileEntity.CommandBlock.DOES_TRACK_OUTPUT, this.shadow$getCommandBlock().isTrackOutput()); + if (this.shadow$getCommandBlock().isTrackOutput()) { container.set(Constants.TileEntity.CommandBlock.TRACKED_OUTPUT, LegacyComponentSerializer.legacySection().serialize(SpongeAdventure.asAdventure(this.shadow$getCommandBlock().getLastOutput()))); } return container; @@ -89,8 +90,13 @@ public String identifier() { return this.shadow$getCommandBlock().getName().getString(); } + @SuppressWarnings({"UnstableApiUsage", "deprecation"}) @Override public void sendMessage(final @NonNull Identity identity, final @NonNull Component message, final @NonNull MessageType type) { - this.shadow$getCommandBlock().sendSystemMessage(SpongeAdventure.asVanilla(message)); + final var source = ((BaseCommandBlockAccessor) this.shadow$getCommandBlock()).invoker$createSource(); + if (source == null) { + return; + } + source.sendSystemMessage(SpongeAdventure.asVanilla(message)); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/network/chat/ComponentSerializationMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/network/chat/ComponentSerializationMixin.java index 4039d41a694..8b71cb7920e 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/network/chat/ComponentSerializationMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/network/chat/ComponentSerializationMixin.java @@ -39,7 +39,7 @@ @Mixin(ComponentSerialization.class) public abstract class ComponentSerializationMixin { - @ModifyVariable(method = "lambda$createCodec$6", at = @At(value = "HEAD"), argsOnly = true) + @ModifyVariable(method = "lambda$createCodec$5", at = @At(value = "HEAD"), argsOnly = true) private static Component impl$localizeComponent(final Component input) { final Locale locale = SpongeAdventure.ENCODING_LOCALE.get(); final ServerPlayer player = SpongeAdventure.ENCODING_PLAYER.get(); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/network/chat/Component_SerializerMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/network/chat/Component_SerializerMixin.java index 01ce68a2357..97824574f4a 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/network/chat/Component_SerializerMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/network/chat/Component_SerializerMixin.java @@ -31,7 +31,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -@Mixin(targets = "net/minecraft/network/codec/ByteBufCodecs$35") +@Mixin(targets = "net/minecraft/network/codec/ByteBufCodecs$34") public abstract class Component_SerializerMixin { // inject into the anonymous function to build a gson instance diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java index c4c1efd11f3..7e43945f3bf 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/MinecraftServerMixin.java @@ -39,14 +39,13 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; import net.minecraft.server.ServerFunctionManager; +import net.minecraft.server.Services; import net.minecraft.server.WorldStem; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.progress.LevelLoadListener; -import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.server.packs.resources.ResourceManager; import net.minecraft.server.packs.resources.SimpleReloadInstance; import net.minecraft.server.players.PlayerList; -import net.minecraft.server.players.UserNameToIdResolver; import net.minecraft.util.Unit; import net.minecraft.util.thread.BlockableEventLoop; import net.minecraft.world.Difficulty; @@ -55,7 +54,6 @@ import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; import net.minecraft.world.level.storage.ServerLevelData; -import net.minecraft.world.level.storage.WorldData; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.slf4j.Logger; @@ -111,7 +109,6 @@ import org.spongepowered.common.service.server.SpongeServerScopedServiceProvider; import java.io.IOException; -import java.util.Collection; import java.util.List; import java.util.Locale; import java.util.Map; @@ -130,23 +127,19 @@ public abstract class MinecraftServerMixin implements SpongeServer, MinecraftSer @Shadow private int tickCount; @Shadow @Final private Thread serverThread; @Shadow @Final private ServerFunctionManager functionManager; + @Shadow private volatile boolean isSaving; @Shadow public abstract CommandSourceStack shadow$createCommandSourceStack(); @Shadow public abstract Iterable shadow$getAllLevels(); @Shadow public abstract boolean shadow$isDedicatedServer(); @Shadow public abstract boolean shadow$isRunning(); @Shadow public abstract PlayerList shadow$getPlayerList(); - @Shadow public abstract PackRepository shadow$getPackRepository(); @Shadow public abstract RegistryAccess.Frozen shadow$registryAccess(); - @Shadow public abstract UserNameToIdResolver shadow$nameToIdCache(); - @Shadow public abstract CompletableFuture shadow$reloadResources(final Collection $$0); - @Shadow public abstract WorldData shadow$getWorldData(); - @Shadow public abstract boolean shadow$haveTime(); - @Shadow private volatile boolean isSaving; + @Shadow protected abstract boolean shadow$haveTime(); @Shadow public abstract ResourceManager shadow$getResourceManager(); + @Shadow public abstract Services shadow$services(); // @formatter:on - private final ChatDecorator impl$spongeDecorator = new SpongeChatDecorator(); private @Nullable SpongeServerScopedServiceProvider impl$serviceProvider; protected @Nullable ResourcePackRequest impl$resourcePack; @@ -394,7 +387,7 @@ public boolean saveAllChunks(final boolean suppressLog, final boolean flush, fin // Save the usercache.json file every 10 minutes or if forced to if (isForced || this.tickCount % 6000 == 0) { // We want to save the username cache json, as we normally bypass it. - final var profileCache = this.shadow$nameToIdCache(); + final var profileCache = this.shadow$services().nameToIdCache(); ((GameProfileCacheBridge) profileCache).bridge$setCanSave(true); profileCache.save(); ((GameProfileCacheBridge) profileCache).bridge$setCanSave(false); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedPlayerListMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedPlayerListMixin.java index 08c0700f7d5..631d228d7b3 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedPlayerListMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedPlayerListMixin.java @@ -28,6 +28,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.RegistryLayer; import net.minecraft.server.dedicated.DedicatedPlayerList; +import net.minecraft.server.notifications.EmptyNotificationService; import net.minecraft.server.players.NameAndId; import net.minecraft.server.players.PlayerList; import net.minecraft.world.level.storage.PlayerDataStorage; @@ -46,8 +47,8 @@ public abstract class DedicatedPlayerListMixin extends PlayerList { public DedicatedPlayerListMixin(final MinecraftServer server, final LayeredRegistryAccess registryAccess, - final PlayerDataStorage playerIo, final int maxPlayers) { - super(server, registryAccess, playerIo, maxPlayers); + final PlayerDataStorage playerIo) { + super(server, registryAccess, playerIo, new EmptyNotificationService()); } @Inject(method = "isWhiteListed", at = @At("HEAD"), cancellable = true) 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 6e754a253ee..7dd67e5f6aa 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 @@ -986,7 +986,7 @@ private boolean isPvpAllowed() { var playerRespawnDestination = this.server.getLevel(defaulted); if (playerRespawnDestination == null) { SpongeCommon.logger().warn("The player '{}' respawn location was located in a world that isn't loaded or doesn't exist. This is not safe so " - + "the player will be moved to the spawn of the default world.", player.getGameProfile().getName()); + + "the player will be moved to the spawn of the default world.", player.getGameProfile().name()); playerRespawnDestination = player.getServer().overworld(); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerConfigurationPacketListenerImplMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerConfigurationPacketListenerImplMixin.java index 2b1227d0b9c..9d90350a929 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerConfigurationPacketListenerImplMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerConfigurationPacketListenerImplMixin.java @@ -95,7 +95,7 @@ public abstract class ServerConfigurationPacketListenerImplMixin extends ServerC if (throwable != null) { // An error occurred during login checks so we ask to abort. ((ConnectionBridge) this.connection).bridge$setKickReason(Component.literal("An error occurred checking ban/whitelist status.")); - SpongeCommon.logger().error("An error occurred when checking the ban/whitelist status of {}.", this.gameProfile.getId().toString()); + SpongeCommon.logger().error("An error occurred when checking the ban/whitelist status of {}.", this.gameProfile.id().toString()); SpongeCommon.logger().error(throwable); } else if (componentOpt != null) { // We handle this later @@ -122,7 +122,7 @@ public abstract class ServerConfigurationPacketListenerImplMixin extends ServerC this.impl$skipBanService = true; this.shadow$handleConfigurationFinished($$0); // invalidate just to be sure there is no user cached for the online player anymore - ((SpongeServer) SpongeCommon.server()).userManager().removeFromCache(this.gameProfile.getId()); + ((SpongeServer) SpongeCommon.server()).userManager().removeFromCache(this.gameProfile.id()); } catch (final Exception e) { throw new RuntimeException(e); } finally { @@ -131,7 +131,7 @@ public abstract class ServerConfigurationPacketListenerImplMixin extends ServerC return null; }, SpongeCommon.server()).exceptionally(throwable -> { - SpongeCommon.logger().error("Forcibly disconnecting user {}({}) due to an error during login.", this.gameProfile.getName(), this.gameProfile.getId(), throwable); + SpongeCommon.logger().error("Forcibly disconnecting user {}({}) due to an error during login.", this.gameProfile.name(), this.gameProfile.id(), throwable); this.shadow$disconnect(Component.literal("Internal Server Error: unable to complete login.")); return null; }); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerLoginPacketListenerImplMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerLoginPacketListenerImplMixin.java index c4908d7a589..9c20ea7084e 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerLoginPacketListenerImplMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerLoginPacketListenerImplMixin.java @@ -174,7 +174,7 @@ public abstract class ServerLoginPacketListenerImplMixin implements ServerLoginP if (throwable != null) { // An error occurred during login checks so we ask to abort. ((ConnectionBridge) this.connection).bridge$setKickReason(Component.literal("An error occurred checking ban/whitelist status.")); - SpongeCommon.logger().error("An error occurred when checking the ban/whitelist status of {}.", this.authenticatedProfile.getId().toString()); + SpongeCommon.logger().error("An error occurred when checking the ban/whitelist status of {}.", this.authenticatedProfile.id().toString()); SpongeCommon.logger().error(throwable); } else if (componentOpt != null) { // We handle this later @@ -193,7 +193,7 @@ public abstract class ServerLoginPacketListenerImplMixin implements ServerLoginP this.impl$fireAuthEvent(); return null; }, ServerLoginPacketListenerImplMixin.impl$EXECUTOR).exceptionally(throwable -> { - SpongeCommon.logger().error("Forcibly disconnecting user {}({}) due to an error during login.", this.authenticatedProfile.getName(), this.authenticatedProfile.getId(), throwable); + SpongeCommon.logger().error("Forcibly disconnecting user {}({}) due to an error during login.", this.authenticatedProfile.name(), this.authenticatedProfile.id(), throwable); this.shadow$disconnect(Component.literal("Internal Server Error: unable to complete login.")); return null; }); @@ -256,10 +256,10 @@ public void handleKey(final ServerboundKeyPacket packet) { final String username = Objects.requireNonNull(this.requestedUsername, "Player name not initialized"); try { - final ProfileResult $$1 = ServerLoginPacketListenerImplMixin.this.server.getSessionService().hasJoinedServer(username, $$5, this.impl$getAddress()); + final ProfileResult $$1 = ServerLoginPacketListenerImplMixin.this.server.services().sessionService().hasJoinedServer(username, $$5, this.impl$getAddress()); if ($$1 != null) { final GameProfile $$2 = $$1.profile(); - ServerLoginPacketListenerImplMixin.LOGGER.info("UUID of player {} is {}", $$2.getName(), $$2.getId()); + ServerLoginPacketListenerImplMixin.LOGGER.info("UUID of player {} is {}", $$2.name(), $$2.id()); ServerLoginPacketListenerImplMixin.this.shadow$startClientVerification($$2); } else if (ServerLoginPacketListenerImplMixin.this.server.isSingleplayer()) { ServerLoginPacketListenerImplMixin.LOGGER.warn("Failed to verify username but will let them in anyway!"); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCacheMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCacheMixin.java index a3708770f1c..740e1a72059 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCacheMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCacheMixin.java @@ -92,18 +92,18 @@ public abstract class GameProfileCacheMixin implements GameProfileCacheBridge { @Override public void bridge$add(final com.mojang.authlib.GameProfile profile, final boolean full, final boolean signed) { - GameProfileCache_GameProfileInfoAccessor accessor = this.profilesByUUID.get(Objects.requireNonNull(profile, "profile").getId()); + GameProfileCache_GameProfileInfoAccessor accessor = this.profilesByUUID.get(Objects.requireNonNull(profile, "profile").id()); final NameAndId current = accessor == null ? null : accessor.invoker$nameAndId(); // Don't allow basic game profiles to overwrite the contents if already // an entry exists that is full. - if (current != null && Objects.equals(current.id(), profile.getId()) && - Objects.equals(current.name(), profile.getName()) && !full) { + if (current != null && Objects.equals(current.id(), profile.id()) && + Objects.equals(current.name(), profile.name()) && !full) { return; } final var nameAndIDToAdd = new NameAndId(profile); this.shadow$add(nameAndIDToAdd); - accessor = this.profilesByUUID.get(profile.getId()); + accessor = this.profilesByUUID.get(profile.id()); if (accessor == null || accessor.invoker$nameAndId() != nameAndIDToAdd) { return; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java index d4c996cfcf0..b853e3ba933 100755 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java @@ -145,15 +145,16 @@ public abstract class PlayerListMixin implements PlayerListBridge { @Shadow @Final @Mutable private IpBanList ipBans; @Shadow @Final @Mutable private UserWhiteList whitelist; @Shadow @Final private List players; - @Shadow @Final protected int maxPlayers; @Shadow public abstract boolean shadow$canBypassPlayerLimit(NameAndId $$0); @Shadow protected abstract boolean shadow$verifyChatTrusted(final PlayerChatMessage $$0); @Shadow protected abstract void shadow$broadcastChatMessage(final PlayerChatMessage $$0, final Predicate $$1, final net.minecraft.server.level.@Nullable ServerPlayer $$2, final ChatType.Bound $$4); + @Shadow public abstract int shadow$getMaxPlayers(); // @formatter:on + private boolean impl$isRespawnWithPosition = false; private boolean impl$isDuringSystemMessageEvent = false; @@ -235,7 +236,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { if (component != null) { return component; } - if (this.players.size() >= this.maxPlayers && !this.shadow$canBypassPlayerLimit(param1)) { + if (this.players.size() >= this.shadow$getMaxPlayers() && !this.shadow$canBypassPlayerLimit(param1)) { return net.minecraft.network.chat.Component.translatable("multiplayer.disconnect.server_full"); } return null; @@ -265,7 +266,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { if (mcWorld == null) { SpongeCommon.logger().warn("The player '{}' was located in a world that isn't loaded or doesn't exist. This is not safe so " - + "the player will be moved to the spawn of the default world.", mcPlayer.getGameProfile().getName()); + + "the player will be moved to the spawn of the default world.", mcPlayer.getGameProfile().name()); mcWorld = this.server.overworld(); final BlockPos spawnPoint = mcWorld.getSharedSpawnPos(); mcPlayer.setPos(spawnPoint.getX() + 0.5, spawnPoint.getY() + 0.5, spawnPoint.getZ() + 0.5); @@ -365,7 +366,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { ((ServerPlayerBridge) playerIn).bridge$setConnectionMessageToSend(message); } - @Redirect(method = "placeNewPlayer", at = @At(value = "FIELD", target = "Lnet/minecraft/server/players/PlayerList;viewDistance:I")) + @Redirect(method = "placeNewPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;getViewDistance()I")) private int impl$usePerWorldViewDistance(final PlayerList self, final Connection co, final net.minecraft.server.level.ServerPlayer player, final CommonListenerCookie cookie) { return ((ServerLevelDataBridge) player.level().getLevelData()).bridge$viewDistance().orElse(self.getViewDistance()); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/BaseCommandBlockMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/BaseCommandBlockMixin.java index da95a861ee5..bc577d37306 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/BaseCommandBlockMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/BaseCommandBlockMixin.java @@ -28,6 +28,7 @@ import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.identity.Identity; import net.kyori.adventure.text.Component; +import net.minecraft.commands.CommandSource; import net.minecraft.commands.CommandSourceStack; import net.minecraft.world.level.BaseCommandBlock; import org.checkerframework.checker.nullness.qual.NonNull; @@ -37,21 +38,30 @@ import org.spongepowered.common.adventure.SpongeAdventure; import org.spongepowered.common.bridge.commands.CommandSourceProviderBridge; +import javax.annotation.Nullable; + @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); + @Shadow public abstract CommandSourceStack createCommandSourceStack(CommandSource var1); + @Shadow @Nullable protected abstract BaseCommandBlock.CloseableCommandBlockSource shadow$createSource(); // @formatter:on + + @Override public CommandSourceStack bridge$getCommandSource(final Cause cause) { - return this.shadow$createCommandSourceStack(); + return this.createCommandSourceStack(this.shadow$createSource()); } @Override + @SuppressWarnings({"deprecation", "UnstableApiUsage"}) public void sendMessage(final @NonNull Identity identity, final @NonNull Component message, final @NonNull MessageType type) { - this.shadow$sendSystemMessage(SpongeAdventure.asVanilla(message)); + final var source = this.shadow$createSource(); + if (source == null) { + return; + } + source.sendSystemMessage(SpongeAdventure.asVanilla(message)); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/vehicle/MinecartCommandBlockMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/vehicle/MinecartCommandBlockMixin.java index 0a34add990e..1ad89d9829b 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/vehicle/MinecartCommandBlockMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/vehicle/MinecartCommandBlockMixin.java @@ -33,6 +33,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.bridge.commands.CommandSourceProviderBridge; import org.spongepowered.common.bridge.permissions.SubjectBridge; @@ -55,6 +56,6 @@ public abstract class MinecartCommandBlockMixin extends AbstractMinecartMixin im @Override public CommandSourceStack bridge$getCommandSource(final Cause cause) { - return this.commandBlock.createCommandSourceStack(); + return this.commandBlock.createCommandSourceStack(SpongeCommon.server()); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/CommandBlockEntityMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/CommandBlockEntityMixin.java index d9b9b9b3e83..549e45c8cb1 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/CommandBlockEntityMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/CommandBlockEntityMixin.java @@ -33,6 +33,7 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.common.accessor.world.level.BaseCommandBlockAccessor; import org.spongepowered.common.bridge.commands.CommandSourceProviderBridge; import org.spongepowered.common.bridge.permissions.SubjectBridge; @@ -54,7 +55,7 @@ public abstract class CommandBlockEntityMixin implements SubjectBridge, CommandS @Override public CommandSourceStack bridge$getCommandSource(final Cause cause) { - return this.commandBlock.createCommandSourceStack(); + return this.commandBlock.createCommandSourceStack((((BaseCommandBlockAccessor) this.commandBlock).invoker$createSource())); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/ipforward/server/network/ServerLoginPacketListenerImplMixin_IpForward.java b/src/mixins/java/org/spongepowered/common/mixin/ipforward/server/network/ServerLoginPacketListenerImplMixin_IpForward.java index 2943887bfa1..4d63df41972 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/ipforward/server/network/ServerLoginPacketListenerImplMixin_IpForward.java +++ b/src/mixins/java/org/spongepowered/common/mixin/ipforward/server/network/ServerLoginPacketListenerImplMixin_IpForward.java @@ -86,14 +86,14 @@ public abstract class ServerLoginPacketListenerImplMixin_IpForward { if (((ConnectionBridge_IpForward) this.connection).bungeeBridge$getSpoofedUUID() != null) { uuid = ((ConnectionBridge_IpForward) this.connection).bungeeBridge$getSpoofedUUID(); } else { - uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + $$0.getName()).getBytes(StandardCharsets.UTF_8)); + uuid = UUID.nameUUIDFromBytes(("OfflinePlayer:" + $$0.name()).getBytes(StandardCharsets.UTF_8)); } - $$0 = new GameProfile(uuid, $$0.getName()); + $$0 = new GameProfile(uuid, $$0.name()); if (((ConnectionBridge_IpForward) this.connection).bungeeBridge$getSpoofedProfile() != null) { for (final Property property : ((ConnectionBridge_IpForward) this.connection).bungeeBridge$getSpoofedProfile()) { - $$0.getProperties().put(property.name(), property); + $$0.properties().put(property.name(), property); } } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/optimization/world/entity/TamableAnimalMixin_Optimization_Owner.java b/src/mixins/java/org/spongepowered/common/mixin/optimization/world/entity/TamableAnimalMixin_Optimization_Owner.java index 314fc868ffc..ef76807c09b 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/optimization/world/entity/TamableAnimalMixin_Optimization_Owner.java +++ b/src/mixins/java/org/spongepowered/common/mixin/optimization/world/entity/TamableAnimalMixin_Optimization_Owner.java @@ -67,7 +67,7 @@ public EntityReference getOwnerReference() { */ @Overwrite public void setOwner(final @javax.annotation.Nullable LivingEntity entity) { - final var reference = Optional.ofNullable(entity).map(EntityReference::new); + final var reference = Optional.ofNullable(entity).map(EntityReference::of); this.cachedOwner$OwnerId = reference.orElse(null); this.entityData.set(DATA_OWNERUUID_ID, reference); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/dedicated/DedicatedServerMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/dedicated/DedicatedServerMixin_Tracker.java index bc9d975b68a..0ae3cea6ea8 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/dedicated/DedicatedServerMixin_Tracker.java +++ b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/dedicated/DedicatedServerMixin_Tracker.java @@ -49,7 +49,7 @@ @Mixin(DedicatedServer.class) public abstract class DedicatedServerMixin_Tracker { - @Shadow public abstract int shadow$getSpawnProtectionRadius(); + @Shadow public abstract int shadow$spawnProtectionRadius(); /** * @author zml - March 9th, 2016 @@ -71,7 +71,7 @@ public boolean isUnderSpawnProtection(final ServerLevel worldIn, final BlockPos } final BlockPos spawnPoint = worldIn.getSharedSpawnPos(); - final int protectionRadius = this.shadow$getSpawnProtectionRadius(); + final int protectionRadius = this.shadow$spawnProtectionRadius(); return protectionRadius > 0 && Math.max(Math.abs(pos.getX() - spawnPoint.getX()), Math.abs(pos.getZ() - spawnPoint.getZ())) <= protectionRadius diff --git a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/FilterableList.java b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/FilterableList.java index 313026a015f..3cfba5eb7ab 100644 --- a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/FilterableList.java +++ b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/FilterableList.java @@ -39,7 +39,6 @@ import java.util.Arrays; import java.util.List; -import java.util.Objects; import java.util.function.Consumer; import java.util.function.Supplier; @@ -67,7 +66,7 @@ public Screen getScreen() { } public int getBottom() { - return this.getY() + this.headerHeight; + return this.getY() + this.getHeight(); } public E getCurrentHoveredEntry() { @@ -107,10 +106,10 @@ public P setFilterSupplier(final Supplier> filterSupplier) { this.filterSupplier = filterSupplier; return (P) this; } - - public int getRowHeight() { - return this.itemHeight; - } +// +// public int getRowHeight() { +// return this.itemHeight; +// } @Override public int getRowWidth() { @@ -171,27 +170,27 @@ protected void renderListItems(final GuiGraphics $$0, final int $$1, final int $ final int $$4 = this.getRowLeft(); final int $$5 = this.getRowWidth(); - final int $$6 = this.itemHeight - 4; +// final int $$6 = this.itemHeight - 4; final int $$7 = filteredList.size(); - for (int $$8 = 0; $$8 < $$7; ++$$8) { - final int $$9 = this.getRowTop($$8); - final int $$10 = this.getRowBottom($$8); - if ($$10 >= this.getY() && $$9 <= this.getBottom()) { - this.renderItemFromList(filteredList, $$0, $$1, $$2, $$3, $$8, $$4, $$9, $$5, $$6); - } - } +// for (int $$8 = 0; $$8 < $$7; ++$$8) { +// final int $$9 = this.getRowTop($$8); +// final int $$10 = this.getRowBottom($$8); +// if ($$10 >= this.getY() && $$9 <= this.getBottom()) { +// this.renderItemFromList(filteredList, $$0, $$1, $$2, $$3, $$8, $$4, $$9, $$5, $$6); +// } +// } } private void renderItemFromList(final List list, final GuiGraphics $$0, final int $$1, final int $$2, final float $$3, final int $$4, final int $$5, final int $$6, final int $$7, final int $$8) { final E $$9 = list.get($$4); - $$9.renderBack($$0, $$4, $$6, $$5, $$7, $$8, $$1, $$2, Objects.equals(this.getHovered(), $$9), $$3); - if (this.isSelectedItem($$4)) { - final int $$10 = this.isFocused() ? -1 : -8355712; - this.renderSelection($$0, $$6, $$7, $$8, $$10, -16777216); - } +// $$9.render($$0, $$4, $$6, $$5, $$7, $$8, $$1, $$2, Objects.equals(this.getHovered(), $$9), $$3); +// if (this.($$4)) { +// final int $$10 = this.isFocused() ? -1 : -8355712; +// this.renderSelection($$0, $$6, $$7, $$8, $$10, -16777216); +// } - $$9.render($$0, $$4, $$6, $$5, $$7, $$8, $$1, $$2, Objects.equals(this.getHovered(), $$9), $$3); +// $$9.render($$0, $$4, $$6, $$5, $$7, $$8, $$1, $$2, Objects.equals(this.getHovered(), $$9), $$3); } @Override @@ -227,16 +226,16 @@ public P getParentList() { public abstract Bounds getInteractBounds(); - @SuppressWarnings("unchecked") - @Override - public void render(final GuiGraphics stack, final int p_render_1_, final int renderY, final int renderX, final int p_render_4_, - final int p_render_5_, final int mouseX, final int mouseY, final boolean p_render_8_, - final float p_render_9_) { - if (this.getInteractBounds().isInBounds(mouseX, mouseY, renderX, renderY)) { - this.parentList.currentHoveredEntry = (E) this; - } else if (this.parentList.getCurrentHoveredEntry() == this) { - this.parentList.currentHoveredEntry = null; - } - } +// @SuppressWarnings("unchecked") +// @Override +// public void render(final GuiGraphics stack, final int p_render_1_, final int renderY, final int renderX, final int p_render_4_, +// final int p_render_5_, final int mouseX, final int mouseY, final boolean p_render_8_, +// final float p_render_9_) { +// if (this.getInteractBounds().isInBounds(mouseX, mouseY, renderX, renderY)) { +// this.parentList.currentHoveredEntry = (E) this; +// } else if (this.parentList.getCurrentHoveredEntry() == this) { +// this.parentList.currentHoveredEntry = null; +// } +// } } } diff --git a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/PluginSelectionList.java b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/PluginSelectionList.java index e1bb2371155..72a84876bd6 100644 --- a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/PluginSelectionList.java +++ b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/PluginSelectionList.java @@ -50,21 +50,26 @@ public Entry(final PluginSelectionList list, final PluginMetadata metadata) { @Override public Bounds getInteractBounds() { - return new Bounds(0, this.getParentList().getRowWidth(), 0, this.getParentList().getRowHeight()); + return new Bounds(0, this.getParentList().getRowWidth(), 0, this.getParentList().scrollerHeight()); } @Override - public void render(final GuiGraphics stack, final int p_render_1_, final int renderY, final int renderX, final int p_render_4_, - final int p_render_5_, final int mouseX, final int mouseY, final boolean p_render_8_, final float p_render_9_) { - // Draw the name, or ID if name is not present - stack.drawString(this.list.fontRenderer, this.metadata.name().orElse(this.metadata.id()), renderX + 2, renderY + 1, 16777215); + public void renderContent(GuiGraphics var1, int var2, int var3, boolean var4, float var5) { - // Draw the ID if the name is present - if (this.metadata.name().isPresent()) { - stack.drawString(this.list.fontRenderer, this.metadata.id(), renderX + 2, renderY + 12, 8421504); - } } + // @Override +// public void render(final GuiGraphics stack, final int p_render_1_, final int renderY, final int renderX, final int p_render_4_, +// final int p_render_5_, final int mouseX, final int mouseY, final boolean p_render_8_, final float p_render_9_) { +// // Draw the name, or ID if name is not present +// stack.drawString(this.list.fontRenderer, this.metadata.name().orElse(this.metadata.id()), renderX + 2, renderY + 1, 16777215); +// +// // Draw the ID if the name is present +// if (this.metadata.name().isPresent()) { +// stack.drawString(this.list.fontRenderer, this.metadata.id(), renderX + 2, renderY + 12, 8421504); +// } +// } + @Override public boolean mouseClicked(final double p_mouseClicked_1_, final double p_mouseClicked_3_, final int p_mouseClicked_5_, final boolean repeated) { this.getParentList().setSelected(this); From e4c0f7ee484929cd97bae9cc7c6234d50f05808f Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Thu, 4 Sep 2025 23:59:50 -0700 Subject: [PATCH 07/24] feat(minecraft): update to 25w36b Additions: - Added Mannequin entity representation Implementation Notes: - Several changes to accommodate Avatar split from Player - WorldBorder is now per-world it appears - Weather is still "global" - WorldBorder.Settings are a pain to work with and appear to be deprecated in some way... See: https://minecraft.wiki/w/Java_Edition_25w36a See: https://minecraft.wiki/w/Java_Edition_25w36b --- SpongeAPI | 2 +- gradle.properties | 2 +- .../server/level/ServerPlayerAccessor.java | 3 + .../accessor/world/entity/AvatarAccessor.java | 44 +++++++++++ .../world/entity/player/PlayerAccessor.java | 15 +--- .../resources/mixins.sponge.accessors.json | 3 +- .../provider/entity/EntityDataProviders.java | 1 + .../data/provider/entity/MannequinData.java | 45 +++++++++++ .../provider/entity/ServerPlayerData.java | 8 +- .../provider/world/WorldPropertiesData.java | 2 +- .../entity/living/human/HumanEntity.java | 15 ++-- .../phase/packet/PacketPhaseUtil.java | 13 ++-- .../common/server/PerWorldBorderListener.java | 14 ++-- .../world/border/PlayerOwnBorderListener.java | 16 ++-- .../border/SpongeWorldBorderBuilder.java | 4 +- .../world/server/SpongeWorldManager.java | 2 +- .../world/teleport/SpongeTeleportHelper.java | 12 +-- .../EntitySelectorParserMixin_API.java | 78 ++++++++++++------- .../server/level/ServerLevelMixin_API.java | 4 +- .../world/level/LevelReaderMixin_API.java | 2 +- .../border/WorldBorderMixin_Settings_API.java | 50 ++++++------ .../level/chunk/EmptyLevelChunkMixin_API.java | 7 +- .../level/chunk/LevelChunkMixin_API.java | 5 +- .../level/chunk/ProtoChunkMixin_API.java | 6 +- .../server/commands/WeatherCommandMixin.java | 25 ++++-- .../core/server/level/ServerLevelMixin.java | 6 +- .../core/server/level/ServerPlayerMixin.java | 40 ++++++++-- .../ServerCommonPacketListenerImplMixin.java | 2 +- ...rConfigurationPacketListenerImplMixin.java | 2 +- .../core/server/players/PlayerListMixin.java | 6 -- .../mixin/core/world/entity/AvatarMixin.java} | 21 +++-- .../entity/decoration/MannequinMixin.java} | 17 ++-- .../entity/npc/WanderingTraderMixin.java | 2 +- .../core/world/entity/player/PlayerMixin.java | 24 +----- .../mixin/core/world/level/LevelMixin.java | 2 - .../world/level/border/WorldBorderMixin.java | 69 ++++++++-------- .../world/level/chunk/LevelChunkMixin.java | 15 +--- .../chunk/SerializableChunkDataMixin.java | 7 +- ...essor_ListenerAndPacketMixin_Tracker.java} | 31 +++----- .../protocol/PacketUtilsMixin_Tracker.java | 58 -------------- .../level/ServerChunkCacheMixin_Tracker.java | 16 +--- src/mixins/resources/mixins.sponge.core.json | 3 +- .../resources/mixins.sponge.tracker.json | 2 +- .../client/gui/widget/MetadataPanel.java | 7 +- .../client/gui/widget/ScrollPanel.java | 14 ++-- .../gui/widget/list/FilterableList.java | 18 +++-- .../gui/widget/list/PluginSelectionList.java | 3 +- 47 files changed, 401 insertions(+), 342 deletions(-) create mode 100644 src/accessors/java/org/spongepowered/common/accessor/world/entity/AvatarAccessor.java create mode 100644 src/main/java/org/spongepowered/common/data/provider/entity/MannequinData.java rename src/{accessors/java/org/spongepowered/common/accessor/advancements/critereon/MinMaxBounds_IntsAccessor.java => mixins/java/org/spongepowered/common/mixin/core/world/entity/AvatarMixin.java} (71%) rename src/{accessors/java/org/spongepowered/common/accessor/advancements/critereon/MinMaxBounds_DoublesAccessor.java => mixins/java/org/spongepowered/common/mixin/core/world/entity/decoration/MannequinMixin.java} (71%) rename src/mixins/java/org/spongepowered/common/mixin/{core/server/commands/WorldBorderCommandMixin.java => tracker/network/PacketProcessor_ListenerAndPacketMixin_Tracker.java} (59%) delete mode 100644 src/mixins/java/org/spongepowered/common/mixin/tracker/network/protocol/PacketUtilsMixin_Tracker.java diff --git a/SpongeAPI b/SpongeAPI index 42b3bf65c4e..9e38f062da8 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit 42b3bf65c4e499bfd99b8796f1db7b6c7a3b4e95 +Subproject commit 9e38f062da88ff1e866393c569392fb5d9ed54b1 diff --git a/gradle.properties b/gradle.properties index 7c3ff5be982..fed374b10f7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.c mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json,mixins.sponge.test.json superClassChanges=common.superclasschange -minecraftVersion=25w35a +minecraftVersion=25w36b recommendedVersion=0-SNAPSHOT org.gradle.dependency.verification.console=verbose diff --git a/src/accessors/java/org/spongepowered/common/accessor/server/level/ServerPlayerAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/server/level/ServerPlayerAccessor.java index d99f6209cce..a2153f86dba 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/server/level/ServerPlayerAccessor.java +++ b/src/accessors/java/org/spongepowered/common/accessor/server/level/ServerPlayerAccessor.java @@ -24,6 +24,7 @@ */ package org.spongepowered.common.accessor.server.level; +import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import org.spongepowered.asm.mixin.Mixin; @@ -48,4 +49,6 @@ public interface ServerPlayerAccessor { @Invoker("triggerDimensionChangeTriggers") void invoker$triggerDimensionChangeTriggers(final ServerLevel world); @Accessor("containerCounter") int accessor$containerCounter(); + + @Accessor("server") MinecraftServer accessor$server(); } diff --git a/src/accessors/java/org/spongepowered/common/accessor/world/entity/AvatarAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/world/entity/AvatarAccessor.java new file mode 100644 index 00000000000..783a850d405 --- /dev/null +++ b/src/accessors/java/org/spongepowered/common/accessor/world/entity/AvatarAccessor.java @@ -0,0 +1,44 @@ +/* + * 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.accessor.world.entity; + +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.Avatar; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.common.UntransformedAccessorError; + +@Mixin(Avatar.class) +public interface AvatarAccessor { + + @Accessor("DATA_PLAYER_MODE_CUSTOMISATION") static EntityDataAccessor accessor$DATA_PLAYER_MODE_CUSTOMISATION() { + throw new UntransformedAccessorError(); + } + + @Accessor("DATA_PLAYER_MAIN_HAND") static EntityDataAccessor accessor$DATA_PLAYER_MAIN_HAND() { + throw new UntransformedAccessorError(); + } + +} diff --git a/src/accessors/java/org/spongepowered/common/accessor/world/entity/player/PlayerAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/world/entity/player/PlayerAccessor.java index 1a91a66d7ad..b865b4bcd36 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/world/entity/player/PlayerAccessor.java +++ b/src/accessors/java/org/spongepowered/common/accessor/world/entity/player/PlayerAccessor.java @@ -24,7 +24,6 @@ */ package org.spongepowered.common.accessor.world.entity.player; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.world.entity.player.Player; import org.spongepowered.asm.mixin.Mixin; @@ -32,6 +31,8 @@ import org.spongepowered.asm.mixin.gen.Invoker; import org.spongepowered.common.UntransformedAccessorError; +import java.util.OptionalInt; + @Mixin(Player.class) public interface PlayerAccessor { @@ -43,19 +44,11 @@ public interface PlayerAccessor { throw new UntransformedAccessorError(); } - @Accessor("DATA_PLAYER_MODE_CUSTOMISATION") static EntityDataAccessor accessor$DATA_PLAYER_MODE_CUSTOMISATION() { - throw new UntransformedAccessorError(); - } - - @Accessor("DATA_PLAYER_MAIN_HAND") static EntityDataAccessor accessor$DATA_PLAYER_MAIN_HAND() { - throw new UntransformedAccessorError(); - } - - @Accessor("DATA_SHOULDER_LEFT") static EntityDataAccessor accessor$DATA_SHOULDER_LEFT() { + @Accessor("DATA_SHOULDER_PARROT_LEFT") static EntityDataAccessor accessor$DATA_SHOULDER_LEFT() { throw new UntransformedAccessorError(); } - @Accessor("DATA_SHOULDER_RIGHT") static EntityDataAccessor accessor$DATA_SHOULDER_RIGHT() { + @Accessor("DATA_SHOULDER_PARROT_RIGHT") static EntityDataAccessor accessor$DATA_SHOULDER_RIGHT() { throw new UntransformedAccessorError(); } @Invoker("getPermissionLevel") int invoker$getPermissionLevel(); diff --git a/src/accessors/resources/mixins.sponge.accessors.json b/src/accessors/resources/mixins.sponge.accessors.json index 77fd528804f..e9406b20aa8 100644 --- a/src/accessors/resources/mixins.sponge.accessors.json +++ b/src/accessors/resources/mixins.sponge.accessors.json @@ -10,8 +10,6 @@ "mixins": [ "ChatFormattingAccessor", "advancements.CriteriaTriggersAccessor", - "advancements.critereon.MinMaxBounds_DoublesAccessor", - "advancements.critereon.MinMaxBounds_IntsAccessor", "commands.CommandSourceStackAccessor", "commands.arguments.DimensionArgumentAccessor", "commands.arguments.OperationArgumentAccessor", @@ -63,6 +61,7 @@ "world.damagesource.CombatTrackerAccessor", "world.entity.AgableMobAccessor", "world.entity.AreaEffectCloudAccessor", + "world.entity.AvatarAccessor", "world.entity.Display_BlockDisplayAccessor", "world.entity.Display_ItemDisplayAccessor", "world.entity.Display_TextDisplayAccessor", diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/EntityDataProviders.java b/src/main/java/org/spongepowered/common/data/provider/entity/EntityDataProviders.java index 49351a84bee..316257cea65 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/EntityDataProviders.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/EntityDataProviders.java @@ -154,6 +154,7 @@ public void registerProviders() { LivingData.register(this.registrator); LlamaData.register(this.registrator); LocationTargetingData.register(this.registrator); + MannequinData.register(this.registrator); MobData.register(this.registrator); MooshroomData.register(this.registrator); OcelotData.register(this.registrator); diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/MannequinData.java b/src/main/java/org/spongepowered/common/data/provider/entity/MannequinData.java new file mode 100644 index 00000000000..0f63c58994f --- /dev/null +++ b/src/main/java/org/spongepowered/common/data/provider/entity/MannequinData.java @@ -0,0 +1,45 @@ +/* + * 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.data.provider.entity; + +import net.minecraft.world.entity.HumanoidArm; +import net.minecraft.world.entity.decoration.Mannequin; +import org.spongepowered.api.data.Keys; +import org.spongepowered.api.data.type.HandPreference; +import org.spongepowered.common.data.provider.DataProviderRegistrator; + +public final class MannequinData { + private MannequinData() { + } + + public static void register(DataProviderRegistrator registrator) { + registrator + .asMutable(Mannequin.class) + .create(Keys.DOMINANT_HAND) + .get(h -> (HandPreference) (Object) h.getMainArm()) + .set((h, v) -> h.setMainArm((HumanoidArm) (Object) v)) + ; + } +} diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/ServerPlayerData.java b/src/main/java/org/spongepowered/common/data/provider/entity/ServerPlayerData.java index 88bdbcfb6f4..80048ed5607 100644 --- a/src/main/java/org/spongepowered/common/data/provider/entity/ServerPlayerData.java +++ b/src/main/java/org/spongepowered/common/data/provider/entity/ServerPlayerData.java @@ -135,9 +135,9 @@ private static void resendProfile(final ServerPlayer h) { // Remove Entity h.level().getChunkSource().removeEntity(h); // Remove from TabList - h.getServer().getPlayerList().broadcastAll(new ClientboundPlayerInfoRemovePacket(List.of(h.getUUID()))); + ((ServerPlayerAccessor) h).accessor$server().getPlayerList().broadcastAll(new ClientboundPlayerInfoRemovePacket(List.of(h.getUUID()))); // Add back to TabList - h.getServer().getPlayerList().broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(h))); + ((ServerPlayerAccessor) h).accessor$server().getPlayerList().broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(h))); // Add Entity h.level().getChunkSource().addEntity(h); // Reconnect local player @@ -148,10 +148,10 @@ private static void resendProfile(final ServerPlayer h) { // resend remaining player data... (see ServerPlayer#changeDimension) h.connection.send(new ClientboundChangeDifficultyPacket(h.level().getLevelData().getDifficulty(), h.level().getLevelData().isDifficultyLocked())); h.connection.send(new ClientboundPlayerAbilitiesPacket(h.getAbilities())); - final PlayerList playerList = h.getServer().getPlayerList(); + final PlayerList playerList = ((ServerPlayerAccessor) h).accessor$server().getPlayerList(); playerList.sendAllPlayerInfo(h); playerList.sendPlayerPermissionLevel(h); - for(MobEffectInstance $$6 : h.getActiveEffects()) { + for (MobEffectInstance $$6 : h.getActiveEffects()) { h.connection.send(new ClientboundUpdateMobEffectPacket(h.getId(), $$6, false)); } h.connection.send(new ClientboundSetExperiencePacket(h.experienceProgress, h.totalExperience, h.experienceLevel)); diff --git a/src/main/java/org/spongepowered/common/data/provider/world/WorldPropertiesData.java b/src/main/java/org/spongepowered/common/data/provider/world/WorldPropertiesData.java index 73b96f28960..fde1474eb0a 100644 --- a/src/main/java/org/spongepowered/common/data/provider/world/WorldPropertiesData.java +++ b/src/main/java/org/spongepowered/common/data/provider/world/WorldPropertiesData.java @@ -74,7 +74,7 @@ public static void register(final DataProviderRegistrator registrator) { .create(Keys.INITIALIZED) .get(ServerLevelData::isInitialized) .create(Keys.WORLD_BORDER) - .get(h -> (WorldBorder) h.getWorldBorder()) + .get(h -> (WorldBorder) (Object) h.getLegacyWorldBorderSettings().orElse(null)) .create(Keys.WEATHER) .get(SpongeWeather::of) .set(SpongeWeather::apply) diff --git a/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java b/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java index c09b7f5e3a2..84fcf7fa112 100644 --- a/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java +++ b/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java @@ -30,7 +30,6 @@ import com.mojang.serialization.DataResult; import net.kyori.adventure.text.Component; import net.minecraft.core.registries.Registries; -import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.Tag; import net.minecraft.network.chat.HoverEvent; @@ -83,6 +82,7 @@ import org.spongepowered.common.SpongeCommon; import org.spongepowered.common.accessor.network.protocol.game.ClientboundAddEntityPacketAccessor; import org.spongepowered.common.accessor.network.protocol.game.ClientboundPlayerInfoUpdatePacketAccessor; +import org.spongepowered.common.accessor.world.entity.AvatarAccessor; import org.spongepowered.common.accessor.world.entity.LivingEntityAccessor; import org.spongepowered.common.accessor.world.entity.player.PlayerAccessor; import org.spongepowered.common.config.SpongeGameConfigs; @@ -100,6 +100,7 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.OptionalInt; import java.util.UUID; import java.util.stream.Stream; @@ -125,7 +126,7 @@ public HumanEntity(final EntityType type, final Level wor super(type, world); this.fakeProfile = ResolvableProfile.createUnresolved(this.uuid); this.setCanPickUpLoot(true); - this.entityData.set(PlayerAccessor.accessor$DATA_PLAYER_MODE_CUSTOMISATION(), Constants.Sponge.Entity.Human.PLAYER_MODEL_FLAG_ALL); + this.entityData.set(AvatarAccessor.accessor$DATA_PLAYER_MODE_CUSTOMISATION(), Constants.Sponge.Entity.Human.PLAYER_MODEL_FLAG_ALL); } @Override @@ -139,13 +140,15 @@ protected void defineSynchedData(SynchedEntityData.Builder $$0) { $$0.define(LivingEntityAccessor.accessor$DATA_STINGER_COUNT_ID(), 0); $$0.define(LivingEntityAccessor.accessor$SLEEPING_POS_ID(), Optional.empty()); + // Avatar + $$0.define(AvatarAccessor.accessor$DATA_PLAYER_MODE_CUSTOMISATION(), (byte) 0); + $$0.define(AvatarAccessor.accessor$DATA_PLAYER_MAIN_HAND(), (byte) 1); + // Player $$0.define(PlayerAccessor.accessor$DATA_PLAYER_ABSORPTION_ID(), 0.0F); $$0.define(PlayerAccessor.accessor$DATA_SCORE_ID(), 0); - $$0.define(PlayerAccessor.accessor$DATA_PLAYER_MODE_CUSTOMISATION(), (byte) 0); - $$0.define(PlayerAccessor.accessor$DATA_PLAYER_MAIN_HAND(), (byte) 1); - $$0.define(PlayerAccessor.accessor$DATA_SHOULDER_LEFT(), new CompoundTag()); - $$0.define(PlayerAccessor.accessor$DATA_SHOULDER_RIGHT(), new CompoundTag()); + $$0.define(PlayerAccessor.accessor$DATA_SHOULDER_LEFT(), OptionalInt.empty()); + $$0.define(PlayerAccessor.accessor$DATA_SHOULDER_RIGHT(), OptionalInt.empty()); } @Override diff --git a/src/main/java/org/spongepowered/common/event/tracking/phase/packet/PacketPhaseUtil.java b/src/main/java/org/spongepowered/common/event/tracking/phase/packet/PacketPhaseUtil.java index 7c1cc7b4af0..9013c2e40b7 100644 --- a/src/main/java/org/spongepowered/common/event/tracking/phase/packet/PacketPhaseUtil.java +++ b/src/main/java/org/spongepowered/common/event/tracking/phase/packet/PacketPhaseUtil.java @@ -206,9 +206,9 @@ public static boolean allTransactionsInvalid(final List slotTra } @SuppressWarnings({"rawtypes", "unchecked", "deprecation"}) - public static void onProcessPacket(final Packet packetIn, final PacketListener netHandler) { - if (netHandler instanceof ServerGamePacketListenerImpl) { - net.minecraft.server.level.ServerPlayer packetPlayer = ((ServerGamePacketListenerImpl) netHandler).player; + public static void onProcessPacket(final Packet packetIn, final PacketListener netHandler,final Runnable call) { + if (netHandler instanceof ServerGamePacketListenerImpl serverGameImpl) { + net.minecraft.server.level.ServerPlayer packetPlayer = serverGameImpl.player; // Only process the CustomPayload, Respawn & ChunkBatchReceived packets from players if they are dead. if (!packetPlayer.isAlive() && !((PacketBridge) packetIn).bridge$canProcessWhenDead()) { return; @@ -218,8 +218,7 @@ public static void onProcessPacket(final Packet packetIn, final PacketListener n // Don't process movement capture logic if player hasn't moved boolean ignoreMovementCapture; - if (packetIn instanceof ServerboundMovePlayerPacket) { - final ServerboundMovePlayerPacket movingPacket = ((ServerboundMovePlayerPacket) packetIn); + if (packetIn instanceof ServerboundMovePlayerPacket movingPacket) { if (movingPacket instanceof ServerboundMovePlayerPacket.Rot) { ignoreMovementCapture = true; } else if (packetPlayer.getX() == ((ServerboundMovePlayerPacketAccessor) movingPacket).accessor$x() && packetPlayer.getY() == ((ServerboundMovePlayerPacketAccessor) movingPacket).accessor$y() && packetPlayer.getZ() == ((ServerboundMovePlayerPacketAccessor) movingPacket).accessor$z()) { @@ -271,12 +270,12 @@ public static void onProcessPacket(final Packet packetIn, final PacketListener n try (final PhaseContext packetContext = context) { packetContext.buildAndSwitch(); - packetIn.handle(netHandler); + call.run(); } } } } else { // client - packetIn.handle(netHandler); + call.run(); } } diff --git a/src/main/java/org/spongepowered/common/server/PerWorldBorderListener.java b/src/main/java/org/spongepowered/common/server/PerWorldBorderListener.java index b9998a6e979..b9d555897f8 100644 --- a/src/main/java/org/spongepowered/common/server/PerWorldBorderListener.java +++ b/src/main/java/org/spongepowered/common/server/PerWorldBorderListener.java @@ -44,36 +44,36 @@ public PerWorldBorderListener(final ServerLevel world) { } @Override - public void onBorderSizeSet(final WorldBorder border, final double newSize) { + public void onSetSize(final WorldBorder border, final double newSize) { this.sendWorldBorderActionPacket(new ClientboundSetBorderSizePacket(border)); } @Override - public void onBorderSizeLerping(final WorldBorder border, final double oldSize, final double newSize, final long time) { + public void onLerpSize(final WorldBorder border, final double oldSize, final double newSize, final long time) { this.sendWorldBorderActionPacket(new ClientboundSetBorderLerpSizePacket(border)); } @Override - public void onBorderCenterSet(final WorldBorder border, final double x, final double z) { + public void onSetCenter(final WorldBorder border, final double x, final double z) { this.sendWorldBorderActionPacket(new ClientboundSetBorderCenterPacket(border)); } @Override - public void onBorderSetWarningTime(final WorldBorder border, final int newTime) { + public void onSetWarningTime(final WorldBorder border, final int newTime) { this.sendWorldBorderActionPacket(new ClientboundSetBorderWarningDelayPacket(border)); } @Override - public void onBorderSetWarningBlocks(final WorldBorder border, final int newDistance) { + public void onSetWarningBlocks(final WorldBorder border, final int newDistance) { this.sendWorldBorderActionPacket(new ClientboundSetBorderWarningDistancePacket(border)); } @Override - public void onBorderSetDamagePerBlock(final WorldBorder border, final double newAmount) { + public void onSetDamagePerBlock(final WorldBorder border, final double newAmount) { } @Override - public void onBorderSetDamageSafeZOne(final WorldBorder border, final double newSize) { + public void onSetSafeZone(final WorldBorder border, final double newSize) { } private void sendWorldBorderActionPacket(final Packet packet) { diff --git a/src/main/java/org/spongepowered/common/world/border/PlayerOwnBorderListener.java b/src/main/java/org/spongepowered/common/world/border/PlayerOwnBorderListener.java index 52d95011a16..2f80ec9259c 100644 --- a/src/main/java/org/spongepowered/common/world/border/PlayerOwnBorderListener.java +++ b/src/main/java/org/spongepowered/common/world/border/PlayerOwnBorderListener.java @@ -46,38 +46,39 @@ public PlayerOwnBorderListener(final net.minecraft.server.level.ServerPlayer pla } @Override - public void onBorderSizeSet(final WorldBorder border, final double newSize) { + public void onSetSize(final WorldBorder border, final double newSize) { this.sendBorderPacket(new ClientboundSetBorderSizePacket(border)); } @Override - public void onBorderSizeLerping(final WorldBorder border, final double oldSize, final double newSize, final long time) { + public void onLerpSize(final WorldBorder border, final double oldSize, final double newSize, final long time) { this.sendBorderPacket(new ClientboundSetBorderLerpSizePacket(border)); } @Override - public void onBorderCenterSet(final WorldBorder border, final double x, final double z) { + public void onSetCenter(final WorldBorder border, final double x, final double z) { this.sendBorderPacket(new ClientboundSetBorderCenterPacket(border)); } @Override - public void onBorderSetWarningTime(final WorldBorder border, final int newTime) { + public void onSetWarningTime(final WorldBorder border, final int newTime) { this.sendBorderPacket(new ClientboundSetBorderWarningDelayPacket(border)); } @Override - public void onBorderSetWarningBlocks(final WorldBorder border, final int newDistance) { + public void onSetWarningBlocks(final WorldBorder border, final int newDistance) { this.sendBorderPacket(new ClientboundSetBorderWarningDistancePacket(border)); } @Override - public void onBorderSetDamagePerBlock(final WorldBorder border, final double newAmount) { + public void onSetDamagePerBlock(final WorldBorder border, final double newAmount) { } @Override - public void onBorderSetDamageSafeZOne(final WorldBorder border, final double newSize) { + public void onSetSafeZone(final WorldBorder border, final double newSize) { } + /** * This method is for cleaning up the player reference once they disconnect. */ @@ -91,4 +92,5 @@ public void onPlayerDisconnect() { private void sendBorderPacket(final Packet packet) { this.player.connection.send(packet); } + } diff --git a/src/main/java/org/spongepowered/common/world/border/SpongeWorldBorderBuilder.java b/src/main/java/org/spongepowered/common/world/border/SpongeWorldBorderBuilder.java index 550cb0c61f6..80e3318f7eb 100644 --- a/src/main/java/org/spongepowered/common/world/border/SpongeWorldBorderBuilder.java +++ b/src/main/java/org/spongepowered/common/world/border/SpongeWorldBorderBuilder.java @@ -61,7 +61,7 @@ public WorldBorder.Builder from(final WorldBorder border) { @Override public WorldBorder.Builder overworldDefaults() { - return this.from((WorldBorder) net.minecraft.world.level.border.WorldBorder.DEFAULT_SETTINGS); + return this.from((WorldBorder) (Object) net.minecraft.world.level.border.WorldBorder.Settings.DEFAULT); } @Override @@ -145,7 +145,7 @@ public WorldBorder build() throws IllegalStateException { if (this.diameter == -1) { throw new IllegalStateException("The diameter or initial diameter has not been set!"); } - return (WorldBorder) WorldBorder_SettingsAccessor.invoker$new( + return (WorldBorder) (Object) WorldBorder_SettingsAccessor.invoker$new( this.center.x(), this.center.y(), this.damagePerBlock, 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 427e2f20f1e..3e431f0ef9c 100644 --- a/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java +++ b/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java @@ -905,7 +905,7 @@ private ServerLevel createLevel( this.worlds.put(registryKey, world); // Ensure that the world border is registered. - world.getWorldBorder().applySettings(levelData.getWorldBorder()); + levelData.getLegacyWorldBorderSettings().ifPresent(world.getWorldBorder()::applySettings); PlatformHooks.INSTANCE.getWorldHooks().postLoadWorld(world); return world; } diff --git a/src/main/java/org/spongepowered/common/world/teleport/SpongeTeleportHelper.java b/src/main/java/org/spongepowered/common/world/teleport/SpongeTeleportHelper.java index bfac0f8b7cd..4b8a5ce5fd3 100644 --- a/src/main/java/org/spongepowered/common/world/teleport/SpongeTeleportHelper.java +++ b/src/main/java/org/spongepowered/common/world/teleport/SpongeTeleportHelper.java @@ -73,12 +73,12 @@ public Optional findSafeLocation(ServerLocation location, int he private Stream getBlockLocations(ServerLocation worldLocation, int height, int width) { // We don't want to warp outside of the world border, so we want to check that we're within it. - final WorldBorder.Settings worldBorder = (WorldBorder.Settings) worldLocation.world().properties().worldBorder(); - final double radius = worldBorder.getSize() / 2.0D; - int worldBorderMinX = GenericMath.floor(worldBorder.getCenterX() - radius); - int worldBorderMinZ = GenericMath.floor(worldBorder.getCenterZ() - radius); - int worldBorderMaxX = GenericMath.floor(worldBorder.getCenterX() + radius); - int worldBorderMaxZ = GenericMath.floor(worldBorder.getCenterZ() + radius); + final WorldBorder.Settings worldBorder = (WorldBorder.Settings) (Object) worldLocation.world().properties().worldBorder(); + final double radius = worldBorder.size() / 2.0D; + int worldBorderMinX = GenericMath.floor(worldBorder.centerX() - radius); + int worldBorderMinZ = GenericMath.floor(worldBorder.centerZ() - radius); + int worldBorderMaxX = GenericMath.floor(worldBorder.centerX() + radius); + int worldBorderMaxZ = GenericMath.floor(worldBorder.centerZ() + radius); // Get the World and get the maximum Y value. int worldMaxY = worldLocation.world().max().y(); diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/commands/arguments/selector/EntitySelectorParserMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/commands/arguments/selector/EntitySelectorParserMixin_API.java index 2de473599c8..da4b71e6e5f 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/commands/arguments/selector/EntitySelectorParserMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/commands/arguments/selector/EntitySelectorParserMixin_API.java @@ -30,7 +30,6 @@ import com.mojang.brigadier.suggestion.SuggestionsBuilder; import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap; import net.minecraft.advancements.critereon.MinMaxBounds; -import net.minecraft.advancements.critereon.WrappedMinMaxBounds; import net.minecraft.commands.arguments.selector.EntitySelector; import net.minecraft.commands.arguments.selector.EntitySelectorParser; import net.minecraft.core.registries.Registries; @@ -58,8 +57,6 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.common.SpongeCommon; -import org.spongepowered.common.accessor.advancements.critereon.MinMaxBounds_DoublesAccessor; -import org.spongepowered.common.accessor.advancements.critereon.MinMaxBounds_IntsAccessor; import org.spongepowered.common.bridge.commands.arguments.selector.EntitySelectorParserBridge; import org.spongepowered.common.command.selector.SpongeSelectorSortAlgorithm; import org.spongepowered.common.util.Preconditions; @@ -69,7 +66,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; @@ -96,8 +92,8 @@ public abstract class EntitySelectorParserMixin_API implements Selector.Builder @Shadow @Nullable private Double deltaX; @Shadow @Nullable private Double deltaY; @Shadow @Nullable private Double deltaZ; - @Shadow private WrappedMinMaxBounds rotX = WrappedMinMaxBounds.ANY; - @Shadow private WrappedMinMaxBounds rotY = WrappedMinMaxBounds.ANY; + @Shadow private MinMaxBounds.FloatDegrees rotX = MinMaxBounds.FloatDegrees.ANY; + @Shadow private MinMaxBounds.FloatDegrees rotY = MinMaxBounds.FloatDegrees.ANY; @Shadow @Final private List> predicates; @Shadow private boolean currentEntity; @Shadow @Nullable private String playerName; @@ -131,9 +127,12 @@ public abstract class EntitySelectorParserMixin_API implements Selector.Builder @Shadow public abstract void shadow$addPredicate(Predicate p_197401_1_); // @formatter:on - @Nullable private Map> api$scores; - @Nullable private Object2BooleanOpenHashMap api$advancement; - @Nullable private Map> api$criterion; + @Nullable + private Map> api$scores; + @Nullable + private Object2BooleanOpenHashMap api$advancement; + @Nullable + private Map> api$criterion; private boolean api$forceSelf; @Override @@ -172,13 +171,26 @@ public abstract class EntitySelectorParserMixin_API implements Selector.Builder if (range.max() != null && range.max() < 0) { throw new IllegalArgumentException("max must be non-negative"); } - this.distance = MinMaxBounds_DoublesAccessor.invoker$new(Optional.ofNullable(range.min()), Optional.ofNullable(range.max())); + + final Double min = range.min(); + final Double max = range.max(); + if (min == null && max == null) { + this.distance = MinMaxBounds.Doubles.ANY; + } else if (min == null) { + this.distance = MinMaxBounds.Doubles.atMost(max); + } else if (max == null) { + this.distance = MinMaxBounds.Doubles.atLeast(min); + } else if (min <= max) { + this.distance = MinMaxBounds.Doubles.between(min, max); + } else { + this.distance = MinMaxBounds.Doubles.between(max, min); + } return this; } @Override public Selector.@NonNull Builder volume(final org.spongepowered.math.vector.@NonNull Vector3d corner1, - final org.spongepowered.math.vector.@NonNull Vector3d corner2) { + final org.spongepowered.math.vector.@NonNull Vector3d corner2) { final org.spongepowered.math.vector.Vector3d minPoint = corner1.min(corner2); final org.spongepowered.math.vector.Vector3d distance = corner1.max(corner2).sub(minPoint); this.shadow$setX(minPoint.x()); @@ -220,7 +232,7 @@ public abstract class EntitySelectorParserMixin_API implements Selector.Builder @Override public Selector.@NonNull Builder addNotAdvancementCriterion(final @NonNull ResourceKey advancement, - final @NonNull AdvancementCriterion criterion) { + final @NonNull AdvancementCriterion criterion) { return this.api$advancementCriterion(advancement, criterion, true); } @@ -265,7 +277,19 @@ public abstract class EntitySelectorParserMixin_API implements Selector.Builder public Selector.@NonNull Builder experienceLevel(final @NonNull Range<@NonNull Integer> range) { Preconditions.checkArgument(range.min() == null || range.min() >= 0, "min must be non-negative"); Preconditions.checkArgument(range.max() == null || range.max() >= 0, "max must be non-negative"); - this.level = MinMaxBounds_IntsAccessor.invoker$new(Optional.of(range.min()), Optional.of(range.max())); + final Integer min = range.min(); + final Integer max = range.max(); + if (min == null && max == null) { + this.level = MinMaxBounds.Ints.ANY; + } else if (min == null) { + this.level = MinMaxBounds.Ints.atMost(max); + } else if (max == null) { + this.level = MinMaxBounds.Ints.atLeast(min); + } else if (min <= max) { + this.level = MinMaxBounds.Ints.between(min, max); + } else { + this.level = MinMaxBounds.Ints.between(max, min); + } this.shadow$setIncludesEntities(false); return this; } @@ -379,7 +403,7 @@ public abstract class EntitySelectorParserMixin_API implements Selector.Builder } if (this.api$criterion != null) { this.api$criterion.forEach((key, value) -> - value.object2BooleanEntrySet().fastForEach(x -> entries.add(key + "={" + x.getKey() + "=" + x.getBooleanValue() + "}"))); + value.object2BooleanEntrySet().fastForEach(x -> entries.add(key + "={" + x.getKey() + "=" + x.getBooleanValue() + "}"))); } this.api$handle("advancements", "{" + String.join(",", entries) + "}"); this.api$advancement = null; @@ -413,8 +437,8 @@ public abstract class EntitySelectorParserMixin_API implements Selector.Builder this.deltaX = null; this.deltaY = null; this.deltaZ = null; - this.rotX = WrappedMinMaxBounds.ANY; - this.rotY = WrappedMinMaxBounds.ANY; + this.rotX = MinMaxBounds.FloatDegrees.ANY; + this.rotY = MinMaxBounds.FloatDegrees.ANY; this.predicates.clear(); this.currentEntity = false; this.playerName = null; @@ -448,7 +472,7 @@ public abstract class EntitySelectorParserMixin_API implements Selector.Builder } private Selector.@NonNull Builder api$advancementCriterion(final @NonNull ResourceKey advancement, final @NonNull AdvancementCriterion criterion, - final boolean inverted) { + final boolean inverted) { if (this.api$criterion == null) { this.api$criterion = new HashMap<>(); } @@ -465,9 +489,9 @@ public abstract class EntitySelectorParserMixin_API implements Selector.Builder ((EntitySelectorParserBridge) this).bridge$handleValue(name, value, invert); } catch (final CommandSyntaxException ex) { throw new IllegalArgumentException( - String.format("Could not create selector criteria based on input (name = '%s', value = '%s', invert = %s)", name, value, - invert.name()), - ex); + String.format("Could not create selector criteria based on input (name = '%s', value = '%s', invert = %s)", name, value, + invert.name()), + ex); } } @@ -480,19 +504,19 @@ public abstract class EntitySelectorParserMixin_API implements Selector.Builder } - private WrappedMinMaxBounds api$getWrappedBounds(final Range<@NonNull Double> range) { + private MinMaxBounds.FloatDegrees api$getWrappedBounds(final Range<@NonNull Double> range) { final Float a = this.api$floatFromDouble(range.min(), Mth::wrapDegrees); final Float b = this.api$floatFromDouble(range.max(), Mth::wrapDegrees); if (a == null) { - return new WrappedMinMaxBounds(null, b); + return new MinMaxBounds.FloatDegrees(MinMaxBounds.Bounds.atMost(b)); } if (b == null) { - return new WrappedMinMaxBounds(a, null); + return new MinMaxBounds.FloatDegrees(MinMaxBounds.Bounds.atLeast(a)); } if (a <= b) { - return new WrappedMinMaxBounds(a, b); + return new MinMaxBounds.FloatDegrees(MinMaxBounds.Bounds.between(a, b)); } - return new WrappedMinMaxBounds(b, a); + return new MinMaxBounds.FloatDegrees(MinMaxBounds.Bounds.between(b, a)); } private String api$intRangeToStringRepresentation(final @NonNull Range<@NonNull Integer> range) { @@ -501,8 +525,8 @@ public abstract class EntitySelectorParserMixin_API implements Selector.Builder } return String.format("%s..%s", - range.min() == null ? "" : String.valueOf(range.min().intValue()), - range.max() == null ? "" : String.valueOf(range.max().intValue())); + range.min() == null ? "" : String.valueOf(range.min().intValue()), + range.max() == null ? "" : String.valueOf(range.max().intValue())); } } 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 635d1e85e59..9adc9c0b625 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 @@ -343,9 +343,9 @@ public WorldBorder setBorder(final WorldBorder border) { borderBridge.bridge$setAssociatedWorld(this.key()); final WorldBorder worldBorder = borderBridge.bridge$applyFrom(border); if (worldBorder == null) { - return (WorldBorder) net.minecraft.world.level.border.WorldBorder.DEFAULT_SETTINGS; + return (WorldBorder) (Object) net.minecraft.world.level.border.WorldBorder.Settings.DEFAULT; } - this.serverLevelData.setWorldBorder((net.minecraft.world.level.border.WorldBorder.Settings) border); + this.serverLevelData.setLegacyWorldBorderSettings(Optional.of((net.minecraft.world.level.border.WorldBorder.Settings) (Object) border)); return worldBorder; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/LevelReaderMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/LevelReaderMixin_API.java index 05edacf69d2..0e65824c30c 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/LevelReaderMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/LevelReaderMixin_API.java @@ -110,7 +110,7 @@ default WorldBorder border() { default WorldBorder setBorder(final WorldBorder border) { final WorldBorder worldBorder = ((WorldBorderBridge) ((CollisionGetter) this).getWorldBorder()).bridge$applyFrom(border); if (worldBorder == null) { - return (WorldBorder) net.minecraft.world.level.border.WorldBorder.DEFAULT_SETTINGS; + return (WorldBorder) (Object) net.minecraft.world.level.border.WorldBorder.Settings.DEFAULT; } return worldBorder; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/border/WorldBorderMixin_Settings_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/border/WorldBorderMixin_Settings_API.java index 8e4dd5558ec..68985d69c1d 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/border/WorldBorderMixin_Settings_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/border/WorldBorderMixin_Settings_API.java @@ -25,6 +25,9 @@ package org.spongepowered.common.mixin.api.minecraft.world.level.border; import net.minecraft.world.level.border.WorldBorder; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Intrinsic; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.math.vector.Vector2d; @@ -32,57 +35,58 @@ import java.time.Duration; @Mixin(WorldBorder.Settings.class) +@Implements(@Interface(iface = org.spongepowered.api.world.border.WorldBorder.class, prefix = "api$")) public abstract class WorldBorderMixin_Settings_API implements org.spongepowered.api.world.border.WorldBorder { //@formatter:off - @Shadow public abstract double shadow$getCenterX(); - @Shadow public abstract double shadow$getCenterZ(); - @Shadow public abstract double shadow$getDamagePerBlock(); - @Shadow public abstract double shadow$getSafeZone(); - @Shadow public abstract int shadow$getWarningBlocks(); - @Shadow public abstract int shadow$getWarningTime(); - @Shadow public abstract double shadow$getSize(); - @Shadow public abstract long shadow$getSizeLerpTime(); - @Shadow public abstract double shadow$getSizeLerpTarget(); + @Shadow public abstract double shadow$centerX(); + @Shadow public abstract double shadow$centerZ(); + @Shadow public abstract double shadow$damagePerBlock(); + @Shadow public abstract double shadow$safeZone(); + @Shadow public abstract int shadow$warningBlocks(); + @Shadow public abstract int shadow$warningTime(); + @Shadow public abstract double shadow$size(); + @Shadow public abstract long shadow$lerpTime(); + @Shadow public abstract double shadow$lerpTarget(); //@formatter:on @Override public Vector2d center() { - return new Vector2d(this.shadow$getCenterX(), this.shadow$getCenterZ()); + return new Vector2d(this.shadow$centerX(), this.shadow$centerZ()); } @Override public double targetDiameter() { - return this.shadow$getSizeLerpTarget(); + return this.shadow$lerpTarget(); } @Override public Duration timeUntilTargetDiameter() { - return Duration.ofMillis(this.shadow$getSizeLerpTime()); + return Duration.ofMillis(this.shadow$lerpTime()); } @Override public double diameter() { - return this.shadow$getSize(); + return this.shadow$size(); } - @Override - public double safeZone() { - return this.shadow$getSafeZone(); + @Intrinsic + public double api$safeZone() { + return this.shadow$safeZone(); } - @Override - public double damagePerBlock() { - return this.shadow$getDamagePerBlock(); + @Intrinsic + public double api$damagePerBlock() { + return this.shadow$damagePerBlock(); } - @Override - public Duration warningTime() { - return Duration.ofMillis(this.shadow$getWarningTime()); + @Intrinsic + public Duration api$warningTime() { + return Duration.ofMillis(this.shadow$warningTime()); } @Override public int warningDistance() { - return this.shadow$getWarningBlocks(); + return this.shadow$warningBlocks(); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/chunk/EmptyLevelChunkMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/chunk/EmptyLevelChunkMixin_API.java index 3c2c72817b3..6d8553e12a7 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/chunk/EmptyLevelChunkMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/chunk/EmptyLevelChunkMixin_API.java @@ -24,13 +24,14 @@ */ package org.spongepowered.common.mixin.api.minecraft.world.level.chunk; -import net.minecraft.core.Registry; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.LevelHeightAccessor; import net.minecraft.world.level.chunk.EmptyLevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.PalettedContainerFactory; import net.minecraft.world.level.chunk.UpgradeData; import net.minecraft.world.level.levelgen.blending.BlendingData; +import org.jetbrains.annotations.Nullable; import org.spongepowered.api.world.biome.Biome; import org.spongepowered.asm.mixin.Mixin; @@ -38,8 +39,8 @@ public abstract class EmptyLevelChunkMixin_API extends LevelChunkMixin_API { public EmptyLevelChunkMixin_API( - final ChunkPos $$0, final UpgradeData $$1, final LevelHeightAccessor $$2, final Registry $$3, final long $$4, - final LevelChunkSection[] $$5, final BlendingData $$6 + final ChunkPos $$0, final UpgradeData $$1, final LevelHeightAccessor $$2, final PalettedContainerFactory $$3, + final long $$4, final @Nullable LevelChunkSection[] $$5, final @Nullable BlendingData $$6 ) { super($$0, $$1, $$2, $$3, $$4, $$5, $$6); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/chunk/LevelChunkMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/chunk/LevelChunkMixin_API.java index e8bb8cbfce8..96fae23ca05 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/chunk/LevelChunkMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/chunk/LevelChunkMixin_API.java @@ -38,6 +38,7 @@ import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.PalettedContainerFactory; import net.minecraft.world.level.chunk.UpgradeData; import net.minecraft.world.level.entity.EntitySection; import net.minecraft.world.level.entity.EntitySectionStorage; @@ -121,8 +122,8 @@ public abstract class LevelChunkMixin_API extends ChunkAccess implements WorldCh private @Nullable SpongeChunkLayout api$chunkLayout; public LevelChunkMixin_API( - final ChunkPos $$0, final UpgradeData $$1, final LevelHeightAccessor $$2, final Registry $$3, final long $$4, - final LevelChunkSection[] $$5, final BlendingData $$6 + final ChunkPos $$0, final UpgradeData $$1, final LevelHeightAccessor $$2, final PalettedContainerFactory $$3, final long $$4, + final @Nullable LevelChunkSection[] $$5, final @Nullable BlendingData $$6 ) { super($$0, $$1, $$2, $$3, $$4, $$5, $$6); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/chunk/ProtoChunkMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/chunk/ProtoChunkMixin_API.java index 128c8e825f3..3561bd4e241 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/chunk/ProtoChunkMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/chunk/ProtoChunkMixin_API.java @@ -26,13 +26,13 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; -import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.LevelHeightAccessor; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.PalettedContainerFactory; import net.minecraft.world.level.chunk.ProtoChunk; import net.minecraft.world.level.chunk.UpgradeData; import net.minecraft.world.level.chunk.status.ChunkStatus; @@ -86,8 +86,8 @@ public abstract class ProtoChunkMixin_API extends ChunkAccess implements Generat private @Nullable Vector3i api$blockMax; public ProtoChunkMixin_API( - final ChunkPos $$0, final UpgradeData $$1, final LevelHeightAccessor $$2, final Registry $$3, final long $$4, - final LevelChunkSection[] $$5, final BlendingData $$6 + final ChunkPos $$0, final UpgradeData $$1, final LevelHeightAccessor $$2, final PalettedContainerFactory $$3, + final long $$4, final LevelChunkSection[] $$5, final BlendingData $$6 ) { super($$0, $$1, $$2, $$3, $$4, $$5, $$6); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/WeatherCommandMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/WeatherCommandMixin.java index 834ff15da6e..e4014c116cf 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/WeatherCommandMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/WeatherCommandMixin.java @@ -24,24 +24,35 @@ */ package org.spongepowered.common.mixin.core.server.commands; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.minecraft.commands.CommandSourceStack; -import net.minecraft.server.MinecraftServer; import net.minecraft.server.commands.WeatherCommand; import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.RandomSource; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(WeatherCommand.class) public abstract class WeatherCommandMixin { - @Redirect(method = { - "getDuration", + @WrapOperation( + method = "getDuration", + at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;getRandom()Lnet/minecraft/util/RandomSource;") + ) + private static RandomSource impl$useCurrentWorld(final ServerLevel instance, final Operation original, final CommandSourceStack source) { + return original.call(source.getLevel()); + } + + @WrapOperation(method = { "setClear", "setRain", "setThunder" - }, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;overworld()Lnet/minecraft/server/level/ServerLevel;")) - private static ServerLevel impl$useCurrentWorld(final MinecraftServer instance, final CommandSourceStack $$0) { - return $$0.getLevel(); + }, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;setWeatherParameters(IIZZ)V")) + private static void impl$useCurrentWorld( + ServerLevel instance, int delay, int duration, boolean rain, boolean thunder, Operation original, + final CommandSourceStack source + ) { + original.call(source.getLevel(), delay, duration, rain, thunder); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java index 4425ab67848..9ea5a5c4718 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java @@ -62,6 +62,7 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.JukeboxBlockEntity; import net.minecraft.world.level.block.entity.TickingBlockEntity; +import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.LevelStem; import net.minecraft.world.level.dimension.end.EndDragonFight; @@ -368,7 +369,8 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerLevel original.call(self, flush); // per-world WorldInfo/WorldBorder/BossBars - levelData.setWorldBorder(this.getWorldBorder().createSettings()); + final var border = this.getWorldBorder(); + levelData.setLegacyWorldBorderSettings(Optional.of(new WorldBorder.Settings(border))); if (levelData instanceof WorldData worldData) { worldData.setCustomBossEvents(this.bridge$getBossBarManager().save(SpongeCommon.server().registryAccess())); this.bridge$getLevelSave().saveDataTag(SpongeCommon.server().registryAccess(), worldData, this.shadow$dimension() == Level.OVERWORLD ? SpongeCommon.server().getPlayerList().getSingleplayerData() : null); @@ -458,7 +460,7 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerLevel } private void impl$setWorldOnBorder() { - ((WorldBorderBridge) this.shadow$getWorldBorder()).bridge$setAssociatedWorld(((ServerWorld) this).key()); + ((WorldBorderBridge) this.getWorldBorder()).bridge$setAssociatedWorld(((ServerWorld) this).key()); } @Inject(method = "globalLevelEvent", at = @At("HEAD"), cancellable = true) 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 7dd67e5f6aa..45ed29153b4 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 @@ -47,6 +47,7 @@ import net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket; import net.minecraft.resources.ResourceKey; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.ServerScoreboard; import net.minecraft.server.level.ClientInformation; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayerGameMode; @@ -127,6 +128,7 @@ 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.level.ServerPlayerAccessor; import org.spongepowered.common.accessor.server.network.ServerCommonPacketListenerImplAccessor; import org.spongepowered.common.accessor.world.level.portal.TeleportTransitionAccessor; import org.spongepowered.common.adventure.SpongeAdventure; @@ -167,7 +169,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements SubjectBr // @formatter:off @Shadow public ServerGamePacketListenerImpl connection; @Shadow @Final public ServerPlayerGameMode gameMode; - @Shadow @Final public MinecraftServer server; + @Shadow @Final private MinecraftServer server; @Shadow private int lastRecordedExperience; @Shadow private boolean isChangingDimension; @Shadow private net.minecraft.world.phys.Vec3 enteredNetherPosition; @@ -224,6 +226,23 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements SubjectBr return Tristate.FALSE; } + + @WrapOperation( + method = "handleShoulderEntities", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/level/ServerPlayer;playShoulderEntityAmbientSound(Lnet/minecraft/nbt/CompoundTag;)V" + ) + ) + private void impl$ignoreShoulderSoundsWhileVanished( + final net.minecraft.server.level.ServerPlayer thisPlayer, final CompoundTag tag, final Operation original + ) { + if (!this.bridge$vanishState().createsSounds()) { + return; + } + original.call(thisPlayer, tag); + } + @Override protected final boolean impl$setLocation(final boolean isChangeOfWorld, final ServerLevel level, final Vector3d pos) { if (this.shadow$isRemoved()) { @@ -295,7 +314,7 @@ public abstract class ServerPlayerMixin extends PlayerMixin implements SubjectBr @Override public void bridge$initScoreboard() { - ((ServerScoreboardBridge) this.shadow$getScoreboard()).bridge$addPlayer((net.minecraft.server.level.ServerPlayer) (Object) this, true); + ((ServerScoreboardBridge) this.shadow$level().getScoreboard()).bridge$addPlayer((net.minecraft.server.level.ServerPlayer) (Object) this, true); } @Override @@ -836,9 +855,18 @@ public void sendMessage(final OutgoingChatMessage $$0, final boolean $$1, final } } - @Override - public net.minecraft.world.scores.Scoreboard shadow$getScoreboard() { - return (net.minecraft.world.scores.Scoreboard) this.impl$scoreboard; + @WrapOperation(method = { + "updateScoreForCriteria", + "die", + "awardKillScore", + "handleTeamKill", + "awardStat", + "resetStat", + }, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;getScoreboard()Lnet/minecraft/server/ServerScoreboard;")) + private ServerScoreboard impl$usePerPlayerScoreboard( + final ServerLevel instance, final Operation original + ) { + return (ServerScoreboard) this.impl$scoreboard; } @Override @@ -987,7 +1015,7 @@ private boolean isPvpAllowed() { if (playerRespawnDestination == null) { SpongeCommon.logger().warn("The player '{}' respawn location was located in a world that isn't loaded or doesn't exist. This is not safe so " + "the player will be moved to the spawn of the default world.", player.getGameProfile().name()); - playerRespawnDestination = player.getServer().overworld(); + playerRespawnDestination = ((ServerPlayerAccessor) player).accessor$server().overworld(); } final RespawnPlayerEvent.SelectWorld event = SpongeEventFactory.createRespawnPlayerEventSelectWorld(PhaseTracker.getInstance().currentCause(), diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerCommonPacketListenerImplMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerCommonPacketListenerImplMixin.java index 99aaa23b71f..4a84163cd65 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerCommonPacketListenerImplMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerCommonPacketListenerImplMixin.java @@ -108,7 +108,7 @@ public abstract class ServerCommonPacketListenerImplMixin implements ServerCommo @Inject(method = "handleResourcePackResponse", at = @At( value = "INVOKE", - target = "Lnet/minecraft/network/protocol/PacketUtils;ensureRunningOnSameThread(Lnet/minecraft/network/protocol/Packet;Lnet/minecraft/network/PacketListener;Lnet/minecraft/util/thread/BlockableEventLoop;)V", + target = "Lnet/minecraft/network/protocol/PacketUtils;ensureRunningOnSameThread(Lnet/minecraft/network/protocol/Packet;Lnet/minecraft/network/PacketListener;Lnet/minecraft/network/PacketProcessor;)V", shift = At.Shift.AFTER)) private void impl$onHandleResourcePackResponse(final ServerboundResourcePackPacket $$0, final CallbackInfo ci) { final @Nullable ResourcePackInfo pack = this.impl$resourcePackInfos.get($$0.id()); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerConfigurationPacketListenerImplMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerConfigurationPacketListenerImplMixin.java index 9d90350a929..d215ceecc97 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerConfigurationPacketListenerImplMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/network/ServerConfigurationPacketListenerImplMixin.java @@ -82,7 +82,7 @@ public abstract class ServerConfigurationPacketListenerImplMixin extends ServerC private boolean impl$skipBanService; @Inject(method = "handleConfigurationFinished", cancellable = true, at = @At(value = "INVOKE", - target = "Lnet/minecraft/network/protocol/PacketUtils;ensureRunningOnSameThread(Lnet/minecraft/network/protocol/Packet;Lnet/minecraft/network/PacketListener;Lnet/minecraft/util/thread/BlockableEventLoop;)V")) + target = "Lnet/minecraft/network/protocol/PacketUtils;ensureRunningOnSameThread(Lnet/minecraft/network/protocol/Packet;Lnet/minecraft/network/PacketListener;Lnet/minecraft/network/PacketProcessor;)V")) private void impl$onHandleConfigurationFinished(final ServerboundFinishConfigurationPacket $$0, final CallbackInfo ci) { if (this.impl$skipBanService) { return; diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java index 3fe9ee1f050..42f7b7b5b6b 100755 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java @@ -540,12 +540,6 @@ public abstract class PlayerListMixin implements PlayerListBridge { SpongeCommon.post(event); } - @Redirect(method = "sendLevelInfo", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;overworld()Lnet/minecraft/server/level/ServerLevel;")) - private ServerLevel impl$usePerWorldWorldBorder(final MinecraftServer minecraftServer, final net.minecraft.server.level.ServerPlayer playerIn, - final ServerLevel worldIn) { - return worldIn; - } - private void impl$disconnectClient(final Connection netManager, final Component disconnectMessage, final @Nullable GameProfile profile) { final net.minecraft.network.chat.Component reason = SpongeAdventure.asVanilla(disconnectMessage); diff --git a/src/accessors/java/org/spongepowered/common/accessor/advancements/critereon/MinMaxBounds_IntsAccessor.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/AvatarMixin.java similarity index 71% rename from src/accessors/java/org/spongepowered/common/accessor/advancements/critereon/MinMaxBounds_IntsAccessor.java rename to src/mixins/java/org/spongepowered/common/mixin/core/world/entity/AvatarMixin.java index a931c5acca8..3ab7f182324 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/advancements/critereon/MinMaxBounds_IntsAccessor.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/AvatarMixin.java @@ -22,20 +22,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.accessor.advancements.critereon; +package org.spongepowered.common.mixin.core.world.entity; -import net.minecraft.advancements.critereon.MinMaxBounds; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.Avatar; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; -import org.spongepowered.common.UntransformedInvokerError; +import org.spongepowered.asm.mixin.Shadow; -import java.util.Optional; +@Mixin(Avatar.class) +public abstract class AvatarMixin extends LivingEntityMixin { -@Mixin(MinMaxBounds.Ints.class) -public interface MinMaxBounds_IntsAccessor { - - @Invoker("") static MinMaxBounds.Ints invoker$new(final Optional min, final Optional max) { - throw new UntransformedInvokerError(); - } + //@formatter:off + @Shadow @Final protected static EntityDataAccessor DATA_PLAYER_MODE_CUSTOMISATION; + //@formatter:on } diff --git a/src/accessors/java/org/spongepowered/common/accessor/advancements/critereon/MinMaxBounds_DoublesAccessor.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/decoration/MannequinMixin.java similarity index 71% rename from src/accessors/java/org/spongepowered/common/accessor/advancements/critereon/MinMaxBounds_DoublesAccessor.java rename to src/mixins/java/org/spongepowered/common/mixin/core/world/entity/decoration/MannequinMixin.java index 09e8543900a..10b5feed971 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/advancements/critereon/MinMaxBounds_DoublesAccessor.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/decoration/MannequinMixin.java @@ -22,20 +22,13 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.accessor.advancements.critereon; +package org.spongepowered.common.mixin.core.world.entity.decoration; -import net.minecraft.advancements.critereon.MinMaxBounds; +import org.spongepowered.api.entity.Mannequin; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; -import org.spongepowered.common.UntransformedInvokerError; +import org.spongepowered.common.mixin.core.world.entity.AvatarMixin; -import java.util.Optional; - -@Mixin(MinMaxBounds.Doubles.class) -public interface MinMaxBounds_DoublesAccessor { - - @Invoker("") static MinMaxBounds.Doubles invoker$new(final Optional min, final Optional max) { - throw new UntransformedInvokerError(); - } +@Mixin(net.minecraft.world.entity.decoration.Mannequin.class) +public abstract class MannequinMixin extends AvatarMixin implements Mannequin { } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/npc/WanderingTraderMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/npc/WanderingTraderMixin.java index e29a9d7bf5a..251de521ef6 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/npc/WanderingTraderMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/npc/WanderingTraderMixin.java @@ -42,7 +42,7 @@ public abstract class WanderingTraderMixin { @Inject(method = "tick", at = @At("HEAD"), cancellable = true) private void impl$checkInfiniteTickDelay( - final ServerLevel $$0, final boolean $$1, final boolean $$2, final CallbackInfo cir + final ServerLevel $$0, final boolean $$1, final CallbackInfo cir ) { if (this.tickDelay == Constants.TickConversions.INFINITE_TICKS) { cir.cancel(); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/player/PlayerMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/player/PlayerMixin.java index 8a4507c47af..04a0e4f4ba8 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/player/PlayerMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/player/PlayerMixin.java @@ -28,9 +28,7 @@ import com.mojang.datafixers.util.Either; import net.kyori.adventure.bossbar.BossBar; import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; -import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundEvent; @@ -48,7 +46,6 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.pattern.BlockInWorld; import net.minecraft.world.phys.AABB; -import net.minecraft.world.scores.Scoreboard; import net.minecraft.world.scores.Team; import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.entity.living.Living; @@ -77,7 +74,7 @@ import org.spongepowered.common.event.SpongeCommonEventFactory; import org.spongepowered.common.event.tracking.PhaseTracker; import org.spongepowered.common.item.util.ItemStackUtil; -import org.spongepowered.common.mixin.core.world.entity.LivingEntityMixin; +import org.spongepowered.common.mixin.core.world.entity.AvatarMixin; import org.spongepowered.common.util.Constants; import org.spongepowered.common.util.ExperienceHolderUtil; @@ -87,10 +84,9 @@ import java.util.Set; @Mixin(net.minecraft.world.entity.player.Player.class) -public abstract class PlayerMixin extends LivingEntityMixin implements PlayerBridge, GameProfileHolderBridge, ViewerBridge { +public abstract class PlayerMixin extends AvatarMixin implements PlayerBridge, GameProfileHolderBridge, ViewerBridge { // @formatter: off - @Shadow @Final protected static EntityDataAccessor DATA_PLAYER_MODE_CUSTOMISATION; @Shadow public int experienceLevel; @Shadow public int totalExperience; @Shadow public float experienceProgress; @@ -101,7 +97,6 @@ public abstract class PlayerMixin extends LivingEntityMixin implements PlayerBri @Shadow protected abstract int shadow$getPermissionLevel(); @Shadow public abstract int shadow$getXpNeededForNextLevel(); @Shadow public abstract FoodData shadow$getFoodData(); - @Shadow public abstract Scoreboard shadow$getScoreboard(); @Shadow public abstract boolean shadow$isCreative(); @Shadow public abstract String shadow$getScoreboardName(); @Shadow public abstract void shadow$awardStat(ResourceLocation stat); @@ -109,7 +104,6 @@ public abstract class PlayerMixin extends LivingEntityMixin implements PlayerBri @Shadow public Either shadow$startSleepInBed(final BlockPos param0) { return null; // Shadowed } - @Shadow protected abstract void shadow$playShoulderEntityAmbientSound(CompoundTag p_192028_1_); // @formatter: on private boolean impl$affectsSpawning = true; @@ -202,20 +196,6 @@ public abstract class PlayerMixin extends LivingEntityMixin implements PlayerBri return playerEntity.getName(); } - @Redirect( - method = "aiStep", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/entity/player/Player;playShoulderEntityAmbientSound(Lnet/minecraft/nbt/CompoundTag;)V" - ) - ) - private void impl$ignoreShoulderSoundsWhileVanished(final net.minecraft.world.entity.player.Player thisPlayer, final CompoundTag tag) { - if (!this.bridge$vanishState().createsSounds()) { - return; - } - this.shadow$playShoulderEntityAmbientSound(tag); - } - @Redirect( method = { "playSound(Lnet/minecraft/sounds/SoundEvent;FF)V", diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/LevelMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/LevelMixin.java index 48764abb719..09eebab75b2 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/LevelMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/LevelMixin.java @@ -50,7 +50,6 @@ import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.TickingBlockEntity; -import net.minecraft.world.level.border.WorldBorder; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.storage.LevelData; @@ -109,7 +108,6 @@ public abstract class LevelMixin implements LevelBridge, LevelAccessor { @Shadow public abstract DifficultyInstance shadow$getCurrentDifficultyAt(BlockPos p_175649_1_); @Shadow public abstract boolean shadow$isRaining(); @Shadow public abstract net.minecraft.world.level.block.entity.@Nullable BlockEntity shadow$getBlockEntity(BlockPos p_175625_1_); - @Shadow public abstract WorldBorder shadow$getWorldBorder(); @Shadow public abstract RegistryAccess shadow$registryAccess(); //@Shadow protected abstract void shadow$postGameEventInRadius(@javax.annotation.Nullable net.minecraft.world.entity.Entity $$0, GameEvent $$1, BlockPos $$2, int $$3); // @formatter on diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/border/WorldBorderMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/border/WorldBorderMixin.java index b8c50cba2e8..451758d8dba 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/border/WorldBorderMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/border/WorldBorderMixin.java @@ -59,9 +59,9 @@ public abstract class WorldBorderMixin implements WorldBorderBridge { private void impl$onSetCenter(final double x, final double z, final CallbackInfo ci) { if (this.impl$fireEvent) { final Supplier proposed = - () -> new SpongeWorldBorderBuilder().from(this) - .center(x, z) - .build(); + () -> new SpongeWorldBorderBuilder().from(this) + .center(x, z) + .build(); if (this.impl$suppressOriginalAction(proposed)) { ci.cancel(); } @@ -72,9 +72,9 @@ public abstract class WorldBorderMixin implements WorldBorderBridge { private void impl$onSetSize(final double size, final CallbackInfo ci) { if (this.impl$fireEvent) { final Supplier proposed = - () -> new SpongeWorldBorderBuilder().from(this) - .initialDiameter(size) - .build(); + () -> new SpongeWorldBorderBuilder().from(this) + .initialDiameter(size) + .build(); if (this.impl$suppressOriginalAction(proposed)) { ci.cancel(); } @@ -85,11 +85,11 @@ public abstract class WorldBorderMixin implements WorldBorderBridge { private void impl$onLerping(final double initial, final double target, final long milliseconds, final CallbackInfo ci) { if (this.impl$fireEvent) { final Supplier proposed = - () -> new SpongeWorldBorderBuilder().from(this) - .initialDiameter(initial) - .targetDiameter(target) - .timeToTargetDiameter(Duration.ofMillis(milliseconds)) - .build(); + () -> new SpongeWorldBorderBuilder().from(this) + .initialDiameter(initial) + .targetDiameter(target) + .timeToTargetDiameter(Duration.ofMillis(milliseconds)) + .build(); if (this.impl$suppressOriginalAction(proposed)) { ci.cancel(); } @@ -100,22 +100,22 @@ public abstract class WorldBorderMixin implements WorldBorderBridge { private void impl$onSetWarningBlocks(final int distance, final CallbackInfo ci) { if (this.impl$fireEvent) { final Supplier proposed = - () -> new SpongeWorldBorderBuilder().from(this) - .warningDistance(distance) - .build(); + () -> new SpongeWorldBorderBuilder().from(this) + .warningDistance(distance) + .build(); if (this.impl$suppressOriginalAction(proposed)) { ci.cancel(); } } } - @Inject(method = "setDamageSafeZone", at = @At(value = "HEAD"), cancellable = true) + @Inject(method = "setSafeZone", at = @At(value = "HEAD"), cancellable = true) private void impl$onSetDamageSafeZone(final double size, final CallbackInfo ci) { if (this.impl$fireEvent) { final Supplier proposed = - () -> new SpongeWorldBorderBuilder().from(this) - .safeZone(size) - .build(); + () -> new SpongeWorldBorderBuilder().from(this) + .safeZone(size) + .build(); if (this.impl$suppressOriginalAction(proposed)) { ci.cancel(); } @@ -126,9 +126,9 @@ public abstract class WorldBorderMixin implements WorldBorderBridge { private void impl$onSetDamagePerBlock(final double damagePerBlock, final CallbackInfo ci) { if (this.impl$fireEvent) { final Supplier proposed = - () -> new SpongeWorldBorderBuilder().from(this) - .damagePerBlock(damagePerBlock) - .build(); + () -> new SpongeWorldBorderBuilder().from(this) + .damagePerBlock(damagePerBlock) + .build(); if (this.impl$suppressOriginalAction(proposed)) { ci.cancel(); } @@ -139,9 +139,9 @@ public abstract class WorldBorderMixin implements WorldBorderBridge { private void impl$onSetWarningTime(final int warningTime, final CallbackInfo ci) { if (this.impl$fireEvent) { final Supplier proposed = - () -> new SpongeWorldBorderBuilder().from(this) - .warningTime(Duration.ofSeconds(warningTime)) - .build(); + () -> new SpongeWorldBorderBuilder().from(this) + .warningTime(Duration.ofSeconds(warningTime)) + .build(); if (this.impl$suppressOriginalAction(proposed)) { ci.cancel(); } @@ -159,16 +159,16 @@ public abstract class WorldBorderMixin implements WorldBorderBridge { if (world.isPresent()) { final org.spongepowered.api.world.border.WorldBorder originalNewBorder = supplier.get(); final ChangeWorldBorderEvent.World event = SpongeEventFactory.createChangeWorldBorderEventWorld( - PhaseTracker.getInstance().currentCause(), - Optional.of(originalNewBorder), - Optional.of(originalNewBorder), - Optional.of(this.bridge$asImmutable()), - world.get() + PhaseTracker.getInstance().currentCause(), + Optional.of(originalNewBorder), + Optional.of(originalNewBorder), + Optional.of(this.bridge$asImmutable()), + world.get() ); final boolean isCancelled = Sponge.eventManager().post(event); if (!isCancelled) { final org.spongepowered.api.world.border.WorldBorder toSet = - event.newBorder().orElse((org.spongepowered.api.world.border.WorldBorder) WorldBorder.DEFAULT_SETTINGS); + event.newBorder().orElse((org.spongepowered.api.world.border.WorldBorder) (Object) WorldBorder.Settings.DEFAULT); if (originalNewBorder != toSet) { // set the values, suppress this call. this.impl$fireEvent = false; @@ -184,13 +184,13 @@ public abstract class WorldBorderMixin implements WorldBorderBridge { @Override public org.spongepowered.api.world.border.WorldBorder bridge$asImmutable() { - return (org.spongepowered.api.world.border.WorldBorder) ((WorldBorder) (Object) this).createSettings(); + return (org.spongepowered.api.world.border.WorldBorder) (Object) new WorldBorder.Settings(((WorldBorder) (Object) this)); } @Override public org.spongepowered.api.world.border.@Nullable WorldBorder bridge$applyFrom(final org.spongepowered.api.world.border.WorldBorder worldBorder) { if (!this.impl$fireEvent) { - ((WorldBorder) (Object) this).applySettings((WorldBorder.Settings) worldBorder); + ((WorldBorder) (Object) this).applySettings((WorldBorder.Settings) (Object) worldBorder); return worldBorder; } @@ -201,15 +201,14 @@ public abstract class WorldBorderMixin implements WorldBorderBridge { return this.bridge$asImmutable(); } - final org.spongepowered.api.world.border.WorldBorder defaultSettings = - (org.spongepowered.api.world.border.WorldBorder) WorldBorder.DEFAULT_SETTINGS; + final var defaultSettings = (org.spongepowered.api.world.border.WorldBorder) (Object) WorldBorder.Settings.DEFAULT; toSet = event.newBorder().orElse(defaultSettings); } else { toSet = worldBorder; } this.impl$fireEvent = false; - ((WorldBorder) (Object) this).applySettings((WorldBorder.Settings) toSet); + ((WorldBorder) (Object) this).applySettings((WorldBorder.Settings) (Object) toSet); this.impl$fireEvent = true; return toSet; } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/chunk/LevelChunkMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/chunk/LevelChunkMixin.java index ee2bce6b001..57beb5d15f5 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/chunk/LevelChunkMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/chunk/LevelChunkMixin.java @@ -25,19 +25,18 @@ package org.spongepowered.common.mixin.core.world.level.chunk; import net.minecraft.core.BlockPos; -import net.minecraft.core.Registry; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerChunkCache; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.LevelChunkSection; +import net.minecraft.world.level.chunk.PalettedContainerFactory; import net.minecraft.world.level.chunk.UpgradeData; import net.minecraft.world.level.levelgen.blending.BlendingData; import net.minecraft.world.ticks.LevelChunkTicks; @@ -86,7 +85,7 @@ public abstract class LevelChunkMixin extends ChunkAccess implements LevelChunkBridge, CacheKeyBridge, SpongeMutableDataHolder, SpongeDataHolderBridge, DataCompoundHolder, BlockChunk { // @formatter:off - @Shadow @Final private Level level; + @Shadow @Final Level level; @Shadow private boolean loaded; @Shadow @Nullable public abstract BlockEntity shadow$getBlockEntity(BlockPos pos, net.minecraft.world.level.chunk.LevelChunk.EntityCreationType p_177424_2_); @@ -105,15 +104,7 @@ public abstract class LevelChunkMixin extends ChunkAccess implements LevelChunkB private Map impl$trackedShortBlockPositions = new HashMap<>(); private @Nullable CompoundTag impl$compound; - public LevelChunkMixin( - final ChunkPos $$0, - final UpgradeData $$1, - final LevelHeightAccessor $$2, - final Registry $$3, - final long $$4, - final LevelChunkSection[] $$5, - final BlendingData $$6 - ) { + public LevelChunkMixin(ChunkPos $$0, UpgradeData $$1, LevelHeightAccessor $$2, PalettedContainerFactory $$3, long $$4, @org.jetbrains.annotations.Nullable LevelChunkSection[] $$5, @org.jetbrains.annotations.Nullable BlendingData $$6, Level level) { super($$0, $$1, $$2, $$3, $$4, $$5, $$6); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/chunk/SerializableChunkDataMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/chunk/SerializableChunkDataMixin.java index 247e4c46a97..d4b215e36af 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/chunk/SerializableChunkDataMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/chunk/SerializableChunkDataMixin.java @@ -24,12 +24,12 @@ */ package org.spongepowered.common.mixin.core.world.level.chunk; -import net.minecraft.core.RegistryAccess; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.LevelHeightAccessor; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraft.world.level.chunk.PalettedContainerFactory; import net.minecraft.world.level.chunk.storage.SerializableChunkData; import org.spongepowered.api.data.persistence.DataContainer; import org.spongepowered.api.world.SerializationBehavior; @@ -103,7 +103,10 @@ public abstract class SerializableChunkDataMixin implements SerializableChunkDat } @Inject(method = "parse", at = @At(value = "TAIL")) - private static void tracker$parseSpongeData(final LevelHeightAccessor $$0, final RegistryAccess $$1, final CompoundTag tag, final CallbackInfoReturnable cir) { + private static void tracker$parseSpongeData( + final LevelHeightAccessor ha, final PalettedContainerFactory pcf, final CompoundTag tag, + final CallbackInfoReturnable cir + ) { final var bridge = (SerializableChunkDataBridge) (Object) cir.getReturnValue(); bridge.bridge$parseTrackerData(tag); bridge.bridge$parseDataHolderData(tag); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/WorldBorderCommandMixin.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/network/PacketProcessor_ListenerAndPacketMixin_Tracker.java similarity index 59% rename from src/mixins/java/org/spongepowered/common/mixin/core/server/commands/WorldBorderCommandMixin.java rename to src/mixins/java/org/spongepowered/common/mixin/tracker/network/PacketProcessor_ListenerAndPacketMixin_Tracker.java index c29688d84ee..b6a90c85cae 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/commands/WorldBorderCommandMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/tracker/network/PacketProcessor_ListenerAndPacketMixin_Tracker.java @@ -22,29 +22,22 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.spongepowered.common.mixin.core.server.commands; +package org.spongepowered.common.mixin.tracker.network; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.commands.WorldBorderCommand; -import net.minecraft.server.level.ServerLevel; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import net.minecraft.network.PacketListener; +import net.minecraft.network.protocol.Packet; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.common.event.tracking.phase.packet.PacketPhaseUtil; -@Mixin(WorldBorderCommand.class) -public abstract class WorldBorderCommandMixin { +@Mixin(targets = "net.minecraft.network.PacketProcessor$ListenerAndPacket") +public abstract class PacketProcessor_ListenerAndPacketMixin_Tracker { - @Redirect(method = { - "setDamageBuffer", - "setDamageAmount", - "setWarningTime", - "setWarningDistance", - "getSize", - "setCenter", - "setSize" - }, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;overworld()Lnet/minecraft/server/level/ServerLevel;")) - private static ServerLevel impl$useCurrentWorld(final MinecraftServer instance, final CommandSourceStack $$0) { - return $$0.getLevel(); + @WrapOperation(method = "handle", + at = @At(value = "INVOKE", target = "Lnet/minecraft/network/protocol/Packet;handle(Lnet/minecraft/network/PacketListener;)V")) + private void tracker$redirectProcessPacket(Packet packet, T listener, Operation original) { + PacketPhaseUtil.onProcessPacket(packet, listener, () -> original.call(packet, listener)); } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/tracker/network/protocol/PacketUtilsMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/network/protocol/PacketUtilsMixin_Tracker.java deleted file mode 100644 index 5c35446f881..00000000000 --- a/src/mixins/java/org/spongepowered/common/mixin/tracker/network/protocol/PacketUtilsMixin_Tracker.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.mixin.tracker.network.protocol; - -import net.minecraft.network.PacketListener; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.PacketUtils; -import net.minecraft.util.thread.BlockableEventLoop; -import org.slf4j.Logger; -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; -import org.spongepowered.common.event.tracking.phase.packet.PacketPhaseUtil; - -@Mixin(PacketUtils.class) -public abstract class PacketUtilsMixin_Tracker { - - // @formatter:off - @Shadow @Final private static Logger LOGGER; - // @formatter:on - - @Redirect(method = "ensureRunningOnSameThread(Lnet/minecraft/network/protocol/Packet;Lnet/minecraft/network/PacketListener;Lnet/minecraft/util/thread/BlockableEventLoop;)V", - at = @At(value = "INVOKE", target = "Lnet/minecraft/util/thread/BlockableEventLoop;executeIfPossible(Ljava/lang/Runnable;)V")) - private static void tracker$redirectProcessPacket(BlockableEventLoop threadTaskExecutor, Runnable runnable, - Packet packet, T packetListener, BlockableEventLoop blockableEventLoop) { - threadTaskExecutor.executeIfPossible(() -> { - if (packetListener.isAcceptingMessages()) { - PacketPhaseUtil.onProcessPacket(packet, packetListener); - } else { - LOGGER.debug("Ignoring packet due to disconnection: " + packet); - } - }); - } -} diff --git a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerChunkCacheMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerChunkCacheMixin_Tracker.java index afcd93db052..956a50f2f1d 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerChunkCacheMixin_Tracker.java +++ b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/level/ServerChunkCacheMixin_Tracker.java @@ -62,24 +62,16 @@ public abstract class ServerChunkCacheMixin_Tracker { } } - @WrapOperation( - method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;J)V", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/server/level/ServerLevel;tickCustomSpawners(ZZ)V" - ) - ) + @WrapOperation(method = "tickChunks(Lnet/minecraft/util/profiling/ProfilerFiller;J)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;tickCustomSpawners(Z)V")) private void tracker$wrapGeneratorEntitySpawner( - final ServerLevel serverWorld, - final boolean spawnHostileMobs, - final boolean spawnPeacefulMobs, - final Operation wrapped + final ServerLevel serverWorld, final boolean spawnEnemies, final Operation wrapped ) { try (final PhaseContext<@NonNull ?> context = GenerationPhase.State.WORLD_SPAWNER_SPAWNING .createPhaseContext(PhaseTracker.getWorldInstance(serverWorld)) .world(serverWorld)) { context.buildAndSwitch(); - wrapped.call(serverWorld, spawnHostileMobs, spawnPeacefulMobs); + wrapped.call(serverWorld, spawnEnemies); } } } diff --git a/src/mixins/resources/mixins.sponge.core.json b/src/mixins/resources/mixins.sponge.core.json index de09fe86223..38f464e7b98 100644 --- a/src/mixins/resources/mixins.sponge.core.json +++ b/src/mixins/resources/mixins.sponge.core.json @@ -69,7 +69,6 @@ "server.commands.SaveAllCommandMixin", "server.commands.TeleportCommandMixin", "server.commands.WeatherCommandMixin", - "server.commands.WorldBorderCommandMixin", "server.dedicated.DedicatedPlayerListMixin", "server.level.ChunkHolderMixin", "server.level.ChunkMap_TrackedEntityMixin", @@ -119,6 +118,7 @@ "world.damagesource.DamageSourcesMixin", "world.entity.ActiveChunkReferentMixin", "world.entity.AgableMobMixin", + "world.entity.AvatarMixin", "world.entity.EntityMaxAirMixin", "world.entity.EntityMixin", "world.entity.EntitySelectorMixin", @@ -129,6 +129,7 @@ "world.entity.LightningBoltMixin", "world.entity.LivingEntityMixin", "world.entity.LivingEntityMixin_Damage", + "world.entity.decoration.MannequinMixin", "world.entity.MobMixin", "world.entity.MobMixin_Attack", "world.entity.PortalProcessorMixin", diff --git a/src/mixins/resources/mixins.sponge.tracker.json b/src/mixins/resources/mixins.sponge.tracker.json index fccb4607b18..59ec46ccd60 100644 --- a/src/mixins/resources/mixins.sponge.tracker.json +++ b/src/mixins/resources/mixins.sponge.tracker.json @@ -8,7 +8,7 @@ "CreatorTrackedPlayerMixin_Tracker", "TrackableTypeMixin", "event.TraitMixin_Tracked_Inventory", - "network.protocol.PacketUtilsMixin_Tracker", + "network.PacketProcessor_ListenerAndPacketMixin_Tracker", "server.MinecraftServerMixin_Tracker", "server.TickTaskMixin_Tracker", "server.dedicated.DedicatedServerMixin_Tracker", diff --git a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/MetadataPanel.java b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/MetadataPanel.java index 9bd67bf24d0..3b1f26849cc 100644 --- a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/MetadataPanel.java +++ b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/MetadataPanel.java @@ -34,6 +34,7 @@ import net.minecraft.client.gui.narration.NarratableEntry; import net.minecraft.client.gui.narration.NarratedElementType; import net.minecraft.client.gui.narration.NarrationElementOutput; +import net.minecraft.client.input.MouseButtonEvent; import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -276,11 +277,11 @@ protected void drawPanel(final GuiGraphics stack, final int entryRight, int rela } @Override - public boolean mouseClicked(final double mouseX, final double mouseY, final int button, final boolean repeated) { + public boolean mouseClicked(final MouseButtonEvent event, final boolean repeated) { // Find an entry match for where we clicked final Entry entry = this.getAllEntries().stream() - .filter(e -> e.valueBounds != null && e.valueBounds.isInBounds((int) mouseX, (int) mouseY)) + .filter(e -> e.valueBounds != null && e.valueBounds.isInBounds((int) event.x(), (int) event.y())) .findFirst().orElse(null); if (entry == null) { @@ -292,7 +293,7 @@ public boolean mouseClicked(final double mouseX, final double mouseY, final int this.screen.handleComponentClicked(component.getStyle()); return true; } - return super.mouseClicked(mouseX, mouseY, button, repeated); + return super.mouseClicked(event, repeated); } @Override diff --git a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/ScrollPanel.java b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/ScrollPanel.java index 4e32fa9c1bf..4187c5d871f 100644 --- a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/ScrollPanel.java +++ b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/ScrollPanel.java @@ -33,6 +33,7 @@ import net.minecraft.client.gui.components.Renderable; import net.minecraft.client.gui.components.events.AbstractContainerEventHandler; import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.input.MouseButtonEvent; import java.util.Collections; import java.util.List; @@ -122,11 +123,14 @@ public boolean isMouseOver(final double mouseX, final double mouseY) { } @Override - public boolean mouseClicked(final double mouseX, final double mouseY, final int button, final boolean repeated) { - if (super.mouseClicked(mouseX, mouseY, button, repeated)) { + public boolean mouseClicked(final MouseButtonEvent event, final boolean repeated) { + if (super.mouseClicked(event, repeated)) { return true; } + final var button = event.button(); + final var mouseX = event.x(); + final var mouseY = event.y(); this.scrolling = button == 0 && mouseX >= this.barLeft && mouseX < this.barLeft + this.barWidth; if (this.scrolling) { return true; @@ -139,8 +143,8 @@ public boolean mouseClicked(final double mouseX, final double mouseY, final int } @Override - public boolean mouseReleased(final double p_mouseReleased_1_, final double p_mouseReleased_3_, final int p_mouseReleased_5_) { - if (super.mouseReleased(p_mouseReleased_1_, p_mouseReleased_3_, p_mouseReleased_5_)) { + public boolean mouseReleased(final MouseButtonEvent event) { + if (super.mouseReleased(event)) { return true; } final boolean ret = this.scrolling; @@ -163,7 +167,7 @@ private int getBarHeight() { } @Override - public boolean mouseDragged(final double mouseX, final double mouseY, final int button, final double deltaX, final double deltaY) { + public boolean mouseDragged(final MouseButtonEvent event, final double deltaX, final double deltaY) { if (this.scrolling) { final int maxScroll = this.height - this.getBarHeight(); final double moved = deltaY / maxScroll; diff --git a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/FilterableList.java b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/FilterableList.java index 3cfba5eb7ab..9313a6503bd 100644 --- a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/FilterableList.java +++ b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/FilterableList.java @@ -33,6 +33,7 @@ import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.narration.NarrationSupplier; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.input.MouseButtonEvent; import net.minecraft.network.chat.Component; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.vanilla.util.Bounds; @@ -130,22 +131,29 @@ public void setSelected(@Nullable final E entry) { super.setSelected(entry); } + @Override - public boolean mouseClicked(final double mouseX, final double mouseY, final int button, final boolean repeatedClick) { - this.updateScrolling(mouseX, mouseY, button); + public boolean mouseClicked(final MouseButtonEvent event, final boolean repeatedClick) { + final var mouseX = event.x(); + final var mouseY = event.y(); + final var button = event.button(); + this.updateScrolling(event); if (!this.isMouseOver(mouseX, mouseY)) { return false; } else { final E e = this.getEntryAtPosition(mouseX, mouseY); if (e != null) { - if (e.mouseClicked(mouseX, mouseY, button, repeatedClick)) { + if (e.mouseClicked(event, repeatedClick)) { this.setFocused(e); this.setDragging(true); return true; } } else if (button == 0) { - this.onClick((int) (mouseX - (double) (this.getX() + this.width / 2 - this.getRowWidth() / 2)), - (int) (mouseY - (double) this.getY()) + (int) this.scrollAmount() - 4, repeatedClick); + final var newEvent = new MouseButtonEvent( + (mouseX - (double) (this.getX() + this.width / 2 - this.getRowWidth() / 2)), + (mouseY - (double) this.getY()) + (int) this.scrollAmount() - 4, + event.buttonInfo()); + this.onClick(newEvent, repeatedClick); return true; } diff --git a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/PluginSelectionList.java b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/PluginSelectionList.java index 72a84876bd6..b5da68d66fb 100644 --- a/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/PluginSelectionList.java +++ b/vanilla/src/main/java/org/spongepowered/vanilla/client/gui/widget/list/PluginSelectionList.java @@ -28,6 +28,7 @@ import net.minecraft.client.gui.narration.NarratedElementType; import net.minecraft.client.gui.narration.NarrationElementOutput; import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.input.MouseButtonEvent; import org.spongepowered.plugin.metadata.PluginMetadata; import org.spongepowered.vanilla.util.Bounds; @@ -71,7 +72,7 @@ public void renderContent(GuiGraphics var1, int var2, int var3, boolean var4, fl // } @Override - public boolean mouseClicked(final double p_mouseClicked_1_, final double p_mouseClicked_3_, final int p_mouseClicked_5_, final boolean repeated) { + public boolean mouseClicked(final MouseButtonEvent event, final boolean repeated) { this.getParentList().setSelected(this); return true; } From 85678d8999101b5898e2bf9a3a3cd0c2a82e5fef Mon Sep 17 00:00:00 2001 From: MrHell228 <82652479+MrHell228@users.noreply.github.com> Date: Mon, 15 Sep 2025 20:00:05 +0300 Subject: [PATCH 08/24] Make BlockEntity a delegating DataHolder (#4230) --- .../common/mixin/api/data/DataHolderMixin_API.java | 3 +-- .../world/level/block/entity/BlockEntityMixin.java | 13 ++++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/data/DataHolderMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/data/DataHolderMixin_API.java index 846e1d75c4a..4d2a31a5efc 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/data/DataHolderMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/data/DataHolderMixin_API.java @@ -26,12 +26,11 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.entity.BlockEntity; import org.spongepowered.api.data.DataHolder; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.common.data.holder.SpongeMutableDataHolder; -@Mixin(value = {BlockEntity.class, Entity.class, ItemStack.class}, priority = 899) +@Mixin(value = {Entity.class, ItemStack.class}, priority = 899) public abstract class DataHolderMixin_API implements DataHolder, SpongeMutableDataHolder { } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/BlockEntityMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/BlockEntityMixin.java index 0241fb2ec9c..819c7859b77 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/BlockEntityMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/BlockEntityMixin.java @@ -32,6 +32,8 @@ import net.minecraft.world.level.block.state.BlockState; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.ResourceKey; +import org.spongepowered.api.block.entity.BlockEntity; +import org.spongepowered.api.data.DataHolder; import org.spongepowered.api.world.server.ServerWorld; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -42,13 +44,16 @@ import org.spongepowered.common.bridge.data.DataCompoundHolder; import org.spongepowered.common.bridge.world.level.block.entity.BlockEntityBridge; import org.spongepowered.common.data.DataUtil; +import org.spongepowered.common.data.holder.SpongeMutableDataHolder; import org.spongepowered.common.data.provider.nbt.NBTDataType; import org.spongepowered.common.data.provider.nbt.NBTDataTypes; +import java.util.Arrays; +import java.util.List; import java.util.StringJoiner; @Mixin(net.minecraft.world.level.block.entity.BlockEntity.class) -public abstract class BlockEntityMixin implements BlockEntityBridge, DataCompoundHolder { +public abstract class BlockEntityMixin implements BlockEntityBridge, DataCompoundHolder, SpongeMutableDataHolder { //@formatter:off @Shadow @Final private BlockEntityType type; @@ -119,4 +124,10 @@ protected StringJoiner getPrettyPrinterStringHelper() { public String bridge$getPrettyPrinterString() { return this.getPrettyPrinterStringHelper().toString(); } + + @Override + public List impl$delegateDataHolder() { + final org.spongepowered.api.block.BlockState state = ((BlockEntity) this).block(); + return Arrays.asList(this, state, state.type()); + } } From a5199c40b0b893d6060439c80ec0dd89df731da2 Mon Sep 17 00:00:00 2001 From: aromaa Date: Tue, 23 Sep 2025 00:03:10 +0300 Subject: [PATCH 09/24] Fix InventoryMenu missing viewer --- .../common/bridge/world/inventory/InventoryMenuBridge.java | 4 +++- .../inventory/InventoryMenuMixin_Bridge_Inventory.java | 7 +++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/spongepowered/common/bridge/world/inventory/InventoryMenuBridge.java b/src/main/java/org/spongepowered/common/bridge/world/inventory/InventoryMenuBridge.java index aefd22e8511..a3d5411068e 100644 --- a/src/main/java/org/spongepowered/common/bridge/world/inventory/InventoryMenuBridge.java +++ b/src/main/java/org/spongepowered/common/bridge/world/inventory/InventoryMenuBridge.java @@ -24,7 +24,9 @@ */ package org.spongepowered.common.bridge.world.inventory; -public interface InventoryMenuBridge { +import org.spongepowered.common.bridge.world.inventory.container.ContainerBridge; + +public interface InventoryMenuBridge extends ContainerBridge { void bridge$markClean(); } diff --git a/src/mixins/java/org/spongepowered/common/mixin/inventory/impl/world/inventory/InventoryMenuMixin_Bridge_Inventory.java b/src/mixins/java/org/spongepowered/common/mixin/inventory/impl/world/inventory/InventoryMenuMixin_Bridge_Inventory.java index e7dbd7c7dcc..ae491ca6f15 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/inventory/impl/world/inventory/InventoryMenuMixin_Bridge_Inventory.java +++ b/src/mixins/java/org/spongepowered/common/mixin/inventory/impl/world/inventory/InventoryMenuMixin_Bridge_Inventory.java @@ -24,8 +24,10 @@ */ package org.spongepowered.common.mixin.inventory.impl.world.inventory; +import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.InventoryMenu; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -41,4 +43,9 @@ public abstract class InventoryMenuMixin_Bridge_Inventory implements InventoryMe public void bridge$markClean() { ((PlayerInventoryBridge) this.owner.getInventory()).bridge$markClean(); } + + @Override + public @Nullable ServerPlayer bridge$getViewer() { + return this.owner instanceof final ServerPlayer player ? player : null; + } } From 24999d046be09c2713cdfb5bad032e16e8ae9893 Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Tue, 23 Sep 2025 21:36:59 -0700 Subject: [PATCH 10/24] feat(minecraft): update to 25w37a Changes: - Changed gamerule tag names - Added NoOpSynchronizer to handle vanished entities See: https://minecraft.wiki/w/Java_Edition_25w37a --- SpongeAPI | 2 +- gradle.properties | 2 +- .../server/level/ChunkMapAccessor.java | 2 +- .../data/datasync/NoOpSynchronizer.java | 52 +++++++++++++ .../VanishedFilteringSynchronizer.java | 73 +++++++++++++++++++ .../entity/living/human/HumanEntity.java | 16 ++-- .../world/SpongePositionSourceFactory.java | 2 +- .../minecraft/world/level/LevelMixin_API.java | 4 +- .../level/ChunkMap_TrackedEntityMixin.java | 7 +- .../core/server/level/ServerEntityMixin.java | 52 ++++++------- .../core/server/level/ServerLevelMixin.java | 13 ++-- .../entity/LivingEntityMixin_Inventory.java | 3 +- 12 files changed, 180 insertions(+), 48 deletions(-) create mode 100644 src/main/java/org/spongepowered/common/data/datasync/NoOpSynchronizer.java create mode 100644 src/main/java/org/spongepowered/common/data/datasync/VanishedFilteringSynchronizer.java diff --git a/SpongeAPI b/SpongeAPI index 9e38f062da8..fefaa09423e 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit 9e38f062da88ff1e866393c569392fb5d9ed54b1 +Subproject commit fefaa09423ed515119157d8b3ac598ef8b77ae85 diff --git a/gradle.properties b/gradle.properties index fed374b10f7..fcd673c6e34 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.c mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json,mixins.sponge.test.json superClassChanges=common.superclasschange -minecraftVersion=25w36b +minecraftVersion=25w37a recommendedVersion=0-SNAPSHOT org.gradle.dependency.verification.console=verbose diff --git a/src/accessors/java/org/spongepowered/common/accessor/server/level/ChunkMapAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/server/level/ChunkMapAccessor.java index c24a269be3e..5a0dda5ac37 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/server/level/ChunkMapAccessor.java +++ b/src/accessors/java/org/spongepowered/common/accessor/server/level/ChunkMapAccessor.java @@ -43,7 +43,7 @@ public interface ChunkMapAccessor { @Invoker("saveAllChunks") void invoker$saveAllChunks(boolean flush); - @Invoker("getChunks") Iterable invoker$getChunks(); + @Accessor("visibleChunkMap") Long2ObjectLinkedOpenHashMap accessor$visibleChunkMap(); @Accessor("level") ServerLevel accessor$level(); } diff --git a/src/main/java/org/spongepowered/common/data/datasync/NoOpSynchronizer.java b/src/main/java/org/spongepowered/common/data/datasync/NoOpSynchronizer.java new file mode 100644 index 00000000000..a859256152a --- /dev/null +++ b/src/main/java/org/spongepowered/common/data/datasync/NoOpSynchronizer.java @@ -0,0 +1,52 @@ +/* + * 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.data.datasync; + +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.server.level.ServerEntity; +import net.minecraft.server.level.ServerPlayer; + +import java.util.function.Predicate; + +public record NoOpSynchronizer() implements ServerEntity.Synchronizer { + + public static final NoOpSynchronizer INSTANCE = new NoOpSynchronizer(); + + @Override + public void sendToTrackingPlayers(Packet var1) { + + } + + @Override + public void sendToTrackingPlayersAndSelf(Packet var1) { + + } + + @Override + public void sendToTrackingPlayersFiltered(Packet var1, Predicate var2) { + + } +} diff --git a/src/main/java/org/spongepowered/common/data/datasync/VanishedFilteringSynchronizer.java b/src/main/java/org/spongepowered/common/data/datasync/VanishedFilteringSynchronizer.java new file mode 100644 index 00000000000..79365096ecd --- /dev/null +++ b/src/main/java/org/spongepowered/common/data/datasync/VanishedFilteringSynchronizer.java @@ -0,0 +1,73 @@ +/* + * 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.data.datasync; + +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.server.level.ServerEntity; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Entity; +import org.spongepowered.common.bridge.data.VanishableBridge; + +import java.lang.ref.WeakReference; +import java.util.function.Predicate; + +public record VanishedFilteringSynchronizer( + ServerEntity.Synchronizer proxy, + WeakReference ref +) implements ServerEntity.Synchronizer { + @Override + public void sendToTrackingPlayers(Packet var1) { + if (this.ref.get() instanceof VanishableBridge vb) { + if (!vb.bridge$isInvisible()) { + this.proxy.sendToTrackingPlayers(var1); + } + return; + } + this.proxy.sendToTrackingPlayers(var1); + } + + @Override + public void sendToTrackingPlayersAndSelf(Packet var1) { + if (this.ref.get() instanceof VanishableBridge vb) { + if (!vb.bridge$isInvisible()) { + this.proxy.sendToTrackingPlayersAndSelf(var1); + } + return; + } + this.proxy.sendToTrackingPlayersAndSelf(var1); + } + + @Override + public void sendToTrackingPlayersFiltered(Packet var1, Predicate var2) { + if (this.ref.get() instanceof VanishableBridge vb) { + if (!vb.bridge$isInvisible()) { + this.proxy.sendToTrackingPlayersFiltered(var1, var2); + } + return; + } + this.proxy.sendToTrackingPlayersFiltered(var1, var2); + } +} diff --git a/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java b/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java index 84fcf7fa112..4433905b18d 100644 --- a/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java +++ b/src/main/java/org/spongepowered/common/entity/living/human/HumanEntity.java @@ -86,6 +86,7 @@ import org.spongepowered.common.accessor.world.entity.LivingEntityAccessor; import org.spongepowered.common.accessor.world.entity.player.PlayerAccessor; import org.spongepowered.common.config.SpongeGameConfigs; +import org.spongepowered.common.data.datasync.NoOpSynchronizer; import org.spongepowered.common.launch.Launch; import org.spongepowered.common.profile.SpongeProfileProperty; import org.spongepowered.common.util.Constants; @@ -117,7 +118,7 @@ public static AttributeSupplier createAttributes() { } // A queue of packets waiting to send to players tracking this human - private final Map>>> playerPacketMap = new HashMap<>(); + private final Map>>> playerPacketMap = new HashMap<>(); private ResolvableProfile fakeProfile; private boolean aiDisabled = false, leftHanded = false; @@ -398,8 +399,7 @@ private void respawnOnClient() { this.pushPackets(new ClientboundRemoveEntitiesPacket(this.getId()), this.createPlayerListPacket(EnumSet.allOf(ClientboundPlayerInfoUpdatePacket.Action.class))); this.pushPackets(this.getAddEntityPacket(new ServerEntity( (ServerLevel) this.level(), - this, 1, true, packet -> {}, - (packet, list) -> {} + this, 1, true, NoOpSynchronizer.INSTANCE ))); } @@ -445,7 +445,7 @@ public ClientboundPlayerInfoUpdatePacket createPlayerListPacket(final EnumSet... packets) { + public void pushPackets(final Packet... packets) { this.pushPackets(null, packets); // null = all players } @@ -456,8 +456,8 @@ public void pushPackets(final Packet... packets) { * @param player The player tracking this human * @param packets All packets to send in a single tick */ - public void pushPackets(final @Nullable ServerPlayer player, final Packet... packets) { - final List>> queue; + public void pushPackets(final @Nullable ServerPlayer player, final Packet... packets) { + final List>> queue; if (player == null) { queue = this.playerPacketMap.computeIfAbsent(null, k -> new ArrayList<>()); } else { @@ -472,8 +472,8 @@ public void pushPackets(final @Nullable ServerPlayer player, final Packet... * @param player The player to get packets for (or null for all players) * @return An array of packets to send in a single tick */ - public Stream> popQueuedPackets(final @Nullable ServerPlayer player) { - final List>> queue = this.playerPacketMap.get(player == null ? null : player.getUUID()); + public Stream> popQueuedPackets(final @Nullable ServerPlayer player) { + final List>> queue = this.playerPacketMap.get(player == null ? null : player.getUUID()); return queue == null || queue.isEmpty() ? Stream.empty() : queue.remove(0); } diff --git a/src/main/java/org/spongepowered/common/world/SpongePositionSourceFactory.java b/src/main/java/org/spongepowered/common/world/SpongePositionSourceFactory.java index 338497401d6..c3eb1cc05b0 100644 --- a/src/main/java/org/spongepowered/common/world/SpongePositionSourceFactory.java +++ b/src/main/java/org/spongepowered/common/world/SpongePositionSourceFactory.java @@ -43,7 +43,7 @@ public PositionSource of(final Vector3i position) { @Override public PositionSource of(final int x, final int y, final int z) { - return (PositionSource) new BlockPositionSource(new BlockPos(x, y, z)); + return (PositionSource) (Object) new BlockPositionSource(new BlockPos(x, y, z)); } @Override diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/LevelMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/LevelMixin_API.java index 09146a1a2ae..4aa6bfaee7d 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/LevelMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/LevelMixin_API.java @@ -24,6 +24,7 @@ */ package org.spongepowered.common.mixin.api.minecraft.world.level; +import com.google.common.collect.Iterables; import net.kyori.adventure.sound.Sound; import net.minecraft.core.BlockPos; import net.minecraft.core.RegistryAccess; @@ -181,7 +182,8 @@ public Iterable loadedChunks() { if (chunkProvider instanceof ServerChunkCache) { final ChunkMapAccessor chunkManager = (ChunkMapAccessor) ((ServerChunkCache) chunkProvider).chunkMap; final List chunks = new ArrayList<>(); - chunkManager.invoker$getChunks().forEach(holder -> { + final var visibleChunks = chunkManager.accessor$visibleChunkMap(); + Iterables.unmodifiableIterable(visibleChunks.values()).forEach(holder -> { final WorldChunk chunk = (WorldChunk) holder.getTickingChunk(); if (chunk != null) { chunks.add(chunk); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ChunkMap_TrackedEntityMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ChunkMap_TrackedEntityMixin.java index a3a9a2482d4..87c7b16da99 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ChunkMap_TrackedEntityMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ChunkMap_TrackedEntityMixin.java @@ -28,6 +28,7 @@ import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Local; import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.server.network.ServerPlayerConnection; @@ -57,12 +58,12 @@ public abstract class ChunkMap_TrackedEntityMixin { * 2) We already have the players being iterated * 3) This achieves the same functionality without adding new accessors etc. */ - @Inject(method = "broadcast(Lnet/minecraft/network/protocol/Packet;)V", at = @At(value = "INVOKE", shift = At.Shift.AFTER, + @Inject(method = "sendToTrackingPlayers(Lnet/minecraft/network/protocol/Packet;)V", at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/server/network/ServerPlayerConnection;send(Lnet/minecraft/network/protocol/Packet;)V")) private void impl$sendQueuedHumanPackets(final CallbackInfo ci, @Local final ServerPlayerConnection connection) { if (this.entity instanceof HumanEntity && connection instanceof ServerGamePacketListenerImpl) { final ServerPlayer player = ((ServerGamePacketListenerImpl) connection).player; - final Stream> packets = ((HumanEntity) this.entity).popQueuedPackets(player); + final Stream> packets = ((HumanEntity) this.entity).popQueuedPackets(player); packets.forEach(player.connection::send); } } @@ -74,7 +75,7 @@ public abstract class ChunkMap_TrackedEntityMixin { * entity is being "removed" from clients by way of literally being mimiced being * "untracked". This safeguards the players being updated erroneously. */ - @Inject(method = "broadcast(Lnet/minecraft/network/protocol/Packet;)V", at = @At("HEAD"), cancellable = true) + @Inject(method = "sendToTrackingPlayers(Lnet/minecraft/network/protocol/Packet;)V", at = @At("HEAD"), cancellable = true) private void impl$ignoreVanished(final Packet packet, final CallbackInfo ci) { if (this.entity instanceof VanishableBridge) { if (((VanishableBridge) this.entity).bridge$vanishState().invisible()) { diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerEntityMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerEntityMixin.java index f1a98074f9d..2a56f356b46 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerEntityMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerEntityMixin.java @@ -27,6 +27,7 @@ import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket; import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket; import net.minecraft.network.syncher.SynchedEntityData; @@ -45,15 +46,16 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.common.accessor.world.entity.LivingEntityAccessor; -import org.spongepowered.common.bridge.data.VanishableBridge; import org.spongepowered.common.bridge.server.level.ServerPlayerBridge; +import org.spongepowered.common.data.datasync.VanishedFilteringSynchronizer; import org.spongepowered.common.entity.living.human.HumanEntity; +import java.lang.ref.WeakReference; import java.util.Collection; import java.util.EnumSet; import java.util.List; -import java.util.function.BiConsumer; import java.util.function.Consumer; +import java.util.function.Predicate; import java.util.stream.Stream; @Mixin(ServerEntity.class) @@ -61,10 +63,16 @@ public abstract class ServerEntityMixin { // @formatter:off @Shadow @Final private Entity entity; - @Shadow @Final @Mutable private Consumer> broadcast; + @Shadow @Final @Mutable private ServerEntity.Synchronizer synchronizer; // @formatter:on /** + * @param serverLevel The world + * @param entity The entity being tracked + * @param trackingRange The update frequency + * @param trackMovementDeltas Whether velocity updates are sent + * @param broadcaster The consumer (a method handle for EntityTracker#sendToAllTracking) + * @param ci The callback info * @author gabizou * @reason Because the packets for *most* all entity updates are handled * through this consumer tick, basically all the players tracking the @@ -77,25 +85,13 @@ public abstract class ServerEntityMixin { * any and all players tracking our tracked entity by filtering the consumer first, * then as a fail safe, the EntityTracker mixin. Meanwhile, all other states are updated * just fine. - * - * @param serverLevel The world - * @param entity The entity being tracked - * @param trackingRange The update frequency - * @param trackMovementDeltas Whether velocity updates are sent - * @param broadcaster The consumer (a method handle for EntityTracker#sendToAllTracking) - * @param ci The callback info */ @Inject(method = "", at = @At("TAIL")) - private void impl$wrapConsumer(final ServerLevel serverLevel, final Entity entity, final int trackingRange, - final boolean trackMovementDeltas, final Consumer> broadcaster, - final BiConsumer filter, final CallbackInfo ci) { - this.broadcast = (packet) -> { - if (this.entity instanceof VanishableBridge bridge) { - if (!bridge.bridge$vanishState().invisible()) { - broadcaster.accept(packet); - } - } - }; + private void impl$wrapConsumer( + final ServerLevel serverLevel, final Entity entity, final int trackingRange, + final boolean trackMovementDeltas, final ServerEntity.Synchronizer broadcaster, + final CallbackInfo ci) { + this.synchronizer = new VanishedFilteringSynchronizer(broadcaster, new WeakReference<>(this.entity)); } @Inject(method = "removePairing", at = @At("RETURN")) @@ -139,8 +135,8 @@ public abstract class ServerEntityMixin { if (!(this.entity instanceof final HumanEntity human)) { return; } - final Stream> packets = human.popQueuedPackets(null); - packets.forEach(this.broadcast); + final Stream> packets = human.popQueuedPackets(null); + packets.forEach(this.synchronizer::sendToTrackingPlayers); // Note that this will further call in ChunkManager_EntityTrackerMixin // for any player specific packets to send. } @@ -169,15 +165,19 @@ public abstract class ServerEntityMixin { return packed; } - @WrapOperation(method = "sendChanges", at = @At(value = "INVOKE", target = "Ljava/util/function/BiConsumer;accept(Ljava/lang/Object;Ljava/lang/Object;)V")) - private void impl$sendSetPassengersToSelf(final BiConsumer instance, final Object packet, final Object ignored, final Operation original) { + @WrapOperation(method = "sendChanges", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/server/level/ServerEntity$Synchronizer;sendToTrackingPlayersFiltered(Lnet/minecraft/network/protocol/Packet;Ljava/util/function/Predicate;)V")) + private void impl$sendSetPassengersToSelf( + final ServerEntity.Synchronizer instance, final Packet packet, + final Predicate serverPlayerPredicate, final Operation original) { // When passengers are removed from a player entity, the target // is the player itself, and we need to synchronize it to them. // In vanilla, it is not possible to ride player entities // so we never end up hitting this code path. - original.call(instance, packet, ignored); + original.call(instance, packet, serverPlayerPredicate); if (this.entity instanceof final ServerPlayer player) { - player.connection.send((Packet) packet); + player.connection.send(packet); } } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java index 9ea5a5c4718..1e8da32f40b 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerLevelMixin.java @@ -52,6 +52,7 @@ import net.minecraft.world.RandomSequences; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.ai.village.poi.PoiManager; +import net.minecraft.world.entity.ai.village.poi.PoiRecord; import net.minecraft.world.entity.ai.village.poi.PoiType; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.CustomSpawner; @@ -509,18 +510,20 @@ public abstract class ServerLevelMixin extends LevelMixin implements ServerLevel } } - @Redirect(method = "lambda$updatePOIOnBlockStateChange$14", + @WrapOperation(method = "lambda$updatePOIOnBlockStateChange$15", at = @At( value = "INVOKE", - target = "Lnet/minecraft/world/entity/ai/village/poi/PoiManager;add(Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Holder;)V" + target = "Lnet/minecraft/world/entity/ai/village/poi/PoiManager;add(Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Holder;)Lnet/minecraft/world/entity/ai/village/poi/PoiRecord;" ) ) - private void impl$avoidAddingPoiUpdatesOnUnloadedWorld(final PoiManager manager, final BlockPos pos, final Holder type) { + private PoiRecord impl$avoidAddingPoiUpdatesOnUnloadedWorld( + final PoiManager instance, final BlockPos pos, final Holder type, final Operation original + ) { // Unloaded worlds should not notify PoiManager of changes if (!SpongeCommon.server().levelKeys().contains(this.shadow$dimension())) { - return; + return null; } - manager.add(pos, type); + return original.call(instance, pos, type); } @Inject( diff --git a/src/mixins/java/org/spongepowered/common/mixin/inventory/event/entity/LivingEntityMixin_Inventory.java b/src/mixins/java/org/spongepowered/common/mixin/inventory/event/entity/LivingEntityMixin_Inventory.java index b7a44af5cb8..c007045332f 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/inventory/event/entity/LivingEntityMixin_Inventory.java +++ b/src/mixins/java/org/spongepowered/common/mixin/inventory/event/entity/LivingEntityMixin_Inventory.java @@ -79,8 +79,9 @@ protected LivingEntityMixin_Inventory(final EntityType param0, final Level pa original.call(slot, item); } + @Inject(method = "handleHandSwap", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, - at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerChunkCache;broadcast(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/network/protocol/Packet;)V")) + at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerChunkCache;sendToTrackingPlayers(Lnet/minecraft/world/entity/Entity;Lnet/minecraft/network/protocol/Packet;)V")) protected void inventory$onHandleHandSwap(final Map map, final CallbackInfo ci) { final Slot mainHand = this.impl$getSpongeSlot(EquipmentSlot.MAINHAND); final var lastMainHand = this.lastEquipmentItems.get(EquipmentSlot.MAINHAND); From 9f1b415f9492da5299f1a327c8ce64293ba7a84f Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Tue, 23 Sep 2025 22:53:10 -0700 Subject: [PATCH 11/24] feat(minecraft): update to 1.21.9-pre1 Notable changes: - Updated `mixinextras` to 0.5.0. - Refactored respawn logic to use `LevelData.RespawnData`. - Adjusted spawn position handling across level and player data. See: https://minecraft.wiki/w/Java_Edition_1.21.9_Pre-Release_1 --- gradle.properties | 2 +- gradle/libs.versions.toml | 2 +- gradle/verification-metadata.xml | 8 ++++++++ .../advancement/SpongeAdvancementBuilder.java | 2 +- .../data/provider/world/WorldPropertiesData.java | 11 ++++++++--- .../common/world/server/SpongeWorldManager.java | 13 ++++++++----- .../core/server/level/ServerPlayerMixin.java | 16 +--------------- .../core/server/players/PlayerListMixin.java | 4 ++-- .../world/level/block/EndPortalBlockMixin.java | 2 +- .../level/storage/PrimaryLevelDataMixin.java | 12 ++++++------ .../dedicated/DedicatedServerMixin_Tracker.java | 2 +- .../level/ServerExplosionMixin_Vanilla.java | 11 +++++------ 12 files changed, 43 insertions(+), 42 deletions(-) diff --git a/gradle.properties b/gradle.properties index fcd673c6e34..fdf8fb46f56 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.c mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json,mixins.sponge.test.json superClassChanges=common.superclasschange -minecraftVersion=25w37a +minecraftVersion=1.21.9-pre1 recommendedVersion=0-SNAPSHOT org.gradle.dependency.verification.console=verbose diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a4510edfba6..a18b360a996 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ asm = "9.8" log4j = "2.24.1" forgeAutoRenamingTool = "1.0.6" mixin = "0.8.7" -mixinextras = "0.4.1" +mixinextras = "0.5.0" modlauncher = "10.2.2" securemodules = "2.2.22" fancymodloader = "9.0.16" diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index a83649978f3..5ff83c7aa5f 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -2410,6 +2410,14 @@ + + + + + + + + diff --git a/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementBuilder.java b/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementBuilder.java index 217086de3a7..505a182d0d2 100644 --- a/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementBuilder.java +++ b/src/main/java/org/spongepowered/common/advancement/SpongeAdvancementBuilder.java @@ -72,7 +72,7 @@ public Advancement.Builder.RootStep root() { @Override public Advancement.Builder background(final ResourceKey backgroundPath) { - this.backgroundPath = new ClientAsset((ResourceLocation) (Object) backgroundPath); + this.backgroundPath = new ClientAsset.ResourceTexture((ResourceLocation) (Object) backgroundPath); return this; } diff --git a/src/main/java/org/spongepowered/common/data/provider/world/WorldPropertiesData.java b/src/main/java/org/spongepowered/common/data/provider/world/WorldPropertiesData.java index fde1474eb0a..2969efd9ec0 100644 --- a/src/main/java/org/spongepowered/common/data/provider/world/WorldPropertiesData.java +++ b/src/main/java/org/spongepowered/common/data/provider/world/WorldPropertiesData.java @@ -24,6 +24,7 @@ */ package org.spongepowered.common.data.provider.world; +import net.minecraft.core.GlobalPos; import net.minecraft.world.level.GameType; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.storage.LevelData; @@ -56,15 +57,19 @@ public static void register(final DataProviderRegistrator registrator) { registrator .asMutable(LevelData.class) .create(Keys.SPAWN_POSITION) - .get(h -> VecHelper.toVector3i(h.getSpawnPos())) + .get(h -> VecHelper.toVector3i(h.getRespawnData().pos())) .create(Keys.HARDCORE) .get(LevelData::isHardcore) .create(Keys.WORLD_DIFFICULTY) .get(h -> (Difficulty) (Object) h.getDifficulty()) .asMutable(WritableLevelData.class) .create(Keys.SPAWN_POSITION) - .get(h -> VecHelper.toVector3i(h.getSpawnPos())) - .set((h, v) -> h.setSpawn(VecHelper.toBlockPos(v), h.getSpawnAngle())) + .get(h -> VecHelper.toVector3i(h.getRespawnData().pos())) + .set((h, v) -> h.setSpawn( + new LevelData.RespawnData(new GlobalPos( + h.getRespawnData().dimension(), + VecHelper.toBlockPos(v) + ), h.getRespawnData().pitch(), h.getRespawnData().yaw()))) .asMutable(ServerLevelData.class) .create(Keys.GAME_MODE) .get(h -> (GameMode) (Object) h.getGameType()) 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 3e431f0ef9c..c3a9249a9f1 100644 --- a/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java +++ b/src/main/java/org/spongepowered/common/world/server/SpongeWorldManager.java @@ -32,6 +32,7 @@ import net.minecraft.ReportedException; import net.minecraft.Util; import net.minecraft.core.BlockPos; +import net.minecraft.core.GlobalPos; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.data.worldgen.features.MiscOverworldFeatures; @@ -61,6 +62,7 @@ import net.minecraft.world.level.levelgen.PhantomSpawner; import net.minecraft.world.level.levelgen.WorldOptions; import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; +import net.minecraft.world.level.storage.LevelData; import net.minecraft.world.level.storage.LevelDataAndDimensions; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.PrimaryLevelData; @@ -933,10 +935,10 @@ private ServerLevel prepareLevel(final ServerLevel level) { if (levelDataBridge.bridge$performsSpawnLogic()) { MinecraftServerAccessor.invoker$setInitialSpawn(level, levelData, worldData.worldGenOptions().generateBonusChest(), isDebugGeneration, server.getLevelLoadListener()); } else if (Level.END.equals(level.dimension())) { - levelData.setSpawn(ServerLevel.END_SPAWN_POINT, 0); + levelData.setSpawn(new LevelData.RespawnData(new GlobalPos(level.dimension(), ServerLevel.END_SPAWN_POINT), 0, 0)); } } else if (worldData.worldGenOptions().generateBonusChest()) { - final BlockPos pos = levelData.getSpawnPos(); + final BlockPos pos = levelData.getRespawnData().pos(); final ConfiguredFeature bonusChestFeature = SpongeCommon.vanillaRegistry(Registries.CONFIGURED_FEATURE).getValue(MiscOverworldFeatures.BONUS_CHEST); bonusChestFeature.place(level, level.getChunkSource().getGenerator(), level.random, pos); } @@ -975,7 +977,8 @@ private CompletableFuture loadSpawnChunksAsync(final ServerLevel le MinecraftServerAccessor.accessor$LOGGER().info("Preparing start region for dimension {}", level.dimension().location()); final ServerChunkCache chunkSource = level.getChunkSource(); - level.setDefaultSpawnPos(level.getSharedSpawnPos(), level.getSharedSpawnAngle()); + final var respawnData = level.getRespawnData(); + level.setRespawnData(new LevelData.RespawnData(respawnData.globalPos(), respawnData.pitch(), respawnData.yaw())); final CompletableFuture generationFuture = new CompletableFuture<>(); Sponge.asyncScheduler().submit( @@ -999,10 +1002,10 @@ private CompletableFuture loadSpawnChunksAsync(final ServerLevel le private void loadSpawnChunks(final ServerLevel level) { MinecraftServerAccessor.accessor$LOGGER().info("Preparing start region for dimension {}", level.dimension().location()); - final BlockPos spawnPoint = level.getSharedSpawnPos(); + final var respawnData = level.getRespawnData(); final ServerChunkCache chunkSource = level.getChunkSource(); ((MinecraftServerAccessor) this.server).accessor$nextTickTimeNanos(Util.getNanos()); - level.setDefaultSpawnPos(spawnPoint, level.getSharedSpawnAngle()); + level.setRespawnData(respawnData); ((MinecraftServerAccessor) this.server).accessor$nextTickTimeNanos(Util.getNanos() + 10L * TimeUtil.NANOSECONDS_PER_MILLISECOND); ((MinecraftServerAccessor) this.server).accessor$waitUntilNextTick(); 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 45ed29153b4..ec91e056274 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 @@ -1009,7 +1009,7 @@ private boolean isPvpAllowed() { @Share("sponge:overridden-respawn") final LocalRef> dimension ) { final var config = original.call(player); - final var defaulted = config == null ? Level.OVERWORLD : config.dimension(); + final var defaulted = config == null ? Level.OVERWORLD : config.respawnData().dimension(); var playerRespawnDestination = this.server.getLevel(defaulted); if (playerRespawnDestination == null) { @@ -1042,20 +1042,6 @@ private boolean isPvpAllowed() { return original.call(instance, key); } - @WrapOperation( - method = "findRespawnPositionAndUseSpawnBlock", - at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;overworld()Lnet/minecraft/server/level/ServerLevel;") - ) - private ServerLevel impl$callRespawnPlayerSelectWorld( - final MinecraftServer instance, final Operation original, - @Share("sponge:overridden-respawn") final LocalRef> dimension - ) { - if (dimension.get() != null) { - return instance.getLevel(dimension.get()); - } - return original.call(instance); - } - @Inject(method = "findRespawnPositionAndUseSpawnBlock", at = @At("RETURN")) private void impl$onFindRespawnPositionAndUseSpawnBlock(final CallbackInfoReturnable cir) { ((TeleportTransitionAccessor) (Object) cir.getReturnValue()).accessor$newLevel(this.impl$respawnLevel); diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java index 98ccf4867d6..24fa09a364c 100755 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java @@ -278,7 +278,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { SpongeCommon.logger().warn("The player '{}' was located in a world that isn't loaded or doesn't exist. This is not safe so " + "the player will be moved to the spawn of the default world.", mcPlayer.getGameProfile().name()); mcWorld = this.server.overworld(); - final BlockPos spawnPoint = mcWorld.getSharedSpawnPos(); + final BlockPos spawnPoint = mcWorld.getRespawnData().pos(); mcPlayer.setPos(spawnPoint.getX() + 0.5, spawnPoint.getY() + 0.5, spawnPoint.getZ() + 0.5); } @@ -488,7 +488,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;getX()D"), slice = @Slice( from = @At(value = "NEW", target = "(Lnet/minecraft/network/protocol/game/CommonPlayerSpawnInfo;B)Lnet/minecraft/network/protocol/game/ClientboundRespawnPacket;"), - to = @At(value = "NEW", target = "(Lnet/minecraft/core/BlockPos;F)Lnet/minecraft/network/protocol/game/ClientboundSetDefaultSpawnPositionPacket;") + to = @At(value = "NEW", target = "(Lnet/minecraft/world/level/storage/LevelData$RespawnData;)Lnet/minecraft/network/protocol/game/ClientboundSetDefaultSpawnPositionPacket;") ) ) private double impl$callRespawnPlayerRecreateEvent(final net.minecraft.server.level.ServerPlayer newPlayer, diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/EndPortalBlockMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/EndPortalBlockMixin.java index c331e66722d..0f985a63a76 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/EndPortalBlockMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/EndPortalBlockMixin.java @@ -70,7 +70,7 @@ public abstract class EndPortalBlockMixin implements PortalBlockBridge { return ServerLocation.of((ServerWorld) transition.newLevel(), VecHelper.toVector3d(transition.position())); } - final var sharedSpawnPos = toLevel.getSharedSpawnPos(); + final var sharedSpawnPos = toLevel.getRespawnData().pos(); final var spawnPos = ((net.minecraft.world.entity.Entity) entity).adjustSpawnLocation(toLevel, sharedSpawnPos).getBottomCenter(); return ServerLocation.of((ServerWorld) toLevel, VecHelper.toVector3d(spawnPos)); } 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 1f9f0090dc9..bee0076bc00 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 @@ -32,7 +32,7 @@ import com.mojang.serialization.Dynamic; import com.mojang.serialization.DynamicOps; import net.kyori.adventure.text.Component; -import net.minecraft.core.BlockPos; +import net.minecraft.core.GlobalPos; import net.minecraft.core.Holder; import net.minecraft.core.RegistryAccess; import net.minecraft.core.UUIDUtil; @@ -55,6 +55,7 @@ import net.minecraft.world.level.levelgen.WorldDimensions; import net.minecraft.world.level.levelgen.WorldGenSettings; import net.minecraft.world.level.levelgen.WorldOptions; +import net.minecraft.world.level.storage.LevelData; import net.minecraft.world.level.storage.PrimaryLevelData; import net.minecraft.world.level.storage.ServerLevelData; import net.minecraft.world.level.storage.WorldData; @@ -91,11 +92,10 @@ public abstract class PrimaryLevelDataMixin implements ServerLevelData, WorldDat // @formatter:off @Shadow private LevelSettings settings; - @Shadow private BlockPos spawnPos; - @Shadow private float spawnAngle; + @Shadow private LevelData.RespawnData respawnData; @Shadow public abstract boolean shadow$isDifficultyLocked(); - @Shadow public abstract void shadow$setSpawn(BlockPos p_176143_1_, float p_176143_2_); + @Shadow public abstract void shadow$setSpawn(LevelData.RespawnData $$0); // @formatter:on @Shadow @@ -249,7 +249,7 @@ public abstract class PrimaryLevelDataMixin implements ServerLevelData, WorldDat final Vector3i spawnPos = bridge.bridge$spawnPosition(); if (spawnPos != null) { - this.shadow$setSpawn(VecHelper.toBlockPos(spawnPos), this.spawnAngle); + this.shadow$setSpawn(new RespawnData(new GlobalPos(this.respawnData.dimension(), VecHelper.toBlockPos(spawnPos)),this.respawnData.pitch(), this.respawnData.yaw())); this.impl$customSpawnPosition = true; } @@ -362,7 +362,7 @@ public String toString() { .add("key=" + this.impl$spongeData.key()) .add("worldType=" + this.impl$dimensionType) .add("uniqueId=" + this.impl$spongeData.uniqueId()) - .add("spawn=" + VecHelper.toVector3i(this.spawnPos)) + .add("spawn=" + this.respawnData.toString()) .add("gameType=" + this.getGameType()) .add("hardcore=" + this.isHardcore()) .add("difficulty=" + this.getDifficulty()) diff --git a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/dedicated/DedicatedServerMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/dedicated/DedicatedServerMixin_Tracker.java index 0ae3cea6ea8..e47a30607f6 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/tracker/server/dedicated/DedicatedServerMixin_Tracker.java +++ b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/dedicated/DedicatedServerMixin_Tracker.java @@ -70,7 +70,7 @@ public boolean isUnderSpawnProtection(final ServerLevel worldIn, final BlockPos } } - final BlockPos spawnPoint = worldIn.getSharedSpawnPos(); + final BlockPos spawnPoint = worldIn.getRespawnData().pos(); final int protectionRadius = this.shadow$spawnProtectionRadius(); return protectionRadius > 0 diff --git a/vanilla/src/mixins/java/org/spongepowered/vanilla/mixin/core/world/level/ServerExplosionMixin_Vanilla.java b/vanilla/src/mixins/java/org/spongepowered/vanilla/mixin/core/world/level/ServerExplosionMixin_Vanilla.java index e8ed777f954..28606236790 100644 --- a/vanilla/src/mixins/java/org/spongepowered/vanilla/mixin/core/world/level/ServerExplosionMixin_Vanilla.java +++ b/vanilla/src/mixins/java/org/spongepowered/vanilla/mixin/core/world/level/ServerExplosionMixin_Vanilla.java @@ -24,6 +24,8 @@ */ package org.spongepowered.vanilla.mixin.core.world.level; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; @@ -105,12 +107,9 @@ public abstract class ServerExplosionMixin_Vanilla { return entities; } - @Redirect(method = "hurtEntities", at = @At(value = "NEW", target = "(DDD)Lnet/minecraft/world/phys/Vec3;")) - private Vec3 vanilla$useKnockbackMultiplier(final double $$0, final double $$1, final double $$2) { - // Honor our knockback value from event - return new Vec3($$0 * this.impl$knockbackMultiplier, - $$1 * this.impl$knockbackMultiplier, - $$2 * this.impl$knockbackMultiplier); + @WrapOperation(method = "hurtEntities",at = @At(value = "INVOKE", target = "Lnet/minecraft/world/phys/Vec3;scale(D)Lnet/minecraft/world/phys/Vec3;")) + private Vec3 vanilla$setKnockbackMultiplier(Vec3 instance, double xVel, Operation original) { + return original.call(instance, xVel * this.impl$knockbackMultiplier); } } From 08771a9da2085c3e47397e4be12f6169c2c8a0c0 Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Tue, 23 Sep 2025 23:06:19 -0700 Subject: [PATCH 12/24] fix(gameprofile): update `impl$lookUpViaSponge` to use appropriate NameAndId --- .../mixin/core/server/players/GameProfileCacheMixin.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCacheMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCacheMixin.java index 062f6bc1ba1..f1dcdc8088e 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCacheMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCacheMixin.java @@ -148,10 +148,11 @@ public abstract class GameProfileCacheMixin implements GameProfileCacheBridge { } @Redirect(method = "lookupGameProfile", at = @At(value = "INVOKE", target = "Lcom/mojang/authlib/GameProfileRepository;findProfileByName(Ljava/lang/String;)Ljava/util/Optional;")) - private static Optional impl$lookUpViaSponge(final GameProfileRepository instance, final String name) { + private static Optional impl$lookUpViaSponge(final GameProfileRepository instance, final String name) { final GameProfileManager profileManager = Sponge.server().gameProfileManager(); try { - return Optional.of(SpongeGameProfile.toMcProfile(profileManager.basicProfile(name).join())); + final var join = profileManager.basicProfile(name).join(); + return Optional.of(new com.mojang.authlib.yggdrasil.response.NameAndId(join.uuid(), join.name().orElse(""))); } catch (final Throwable e) { return Optional.empty(); } From ee89a9331eab9beeb404fd7f8e24e88bee65c597 Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Tue, 23 Sep 2025 23:06:38 -0700 Subject: [PATCH 13/24] feat(minecraft): update to 1.21.9-pre2 See: https://minecraft.wiki/w/Java_Edition_1.21.9_Pre-Release_2 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index fdf8fb46f56..d67f6b9e064 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.c mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json,mixins.sponge.test.json superClassChanges=common.superclasschange -minecraftVersion=1.21.9-pre1 +minecraftVersion=1.21.9-pre2 recommendedVersion=0-SNAPSHOT org.gradle.dependency.verification.console=verbose From c8c8a5b62286767ef59ff3d146c2c4201209cc93 Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Tue, 23 Sep 2025 23:22:10 -0700 Subject: [PATCH 14/24] feat(minecraft): update to 1.21.9-pre3 See: https://minecraft.wiki/w/Java_Edition_1.21.9_Pre-Release_3 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index d67f6b9e064..8ff61ee3b4e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.c mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json,mixins.sponge.test.json superClassChanges=common.superclasschange -minecraftVersion=1.21.9-pre2 +minecraftVersion=1.21.9-pre3 recommendedVersion=0-SNAPSHOT org.gradle.dependency.verification.console=verbose From 8596256cab7807c18dcebc568fdae542a36bd563 Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Tue, 23 Sep 2025 23:33:49 -0700 Subject: [PATCH 15/24] feat(minecraft): update to 1.21.9-pre4 See: https://minecraft.wiki/w/Java_Edition_1.21.9_Pre-Release_4 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 8ff61ee3b4e..41511f810c2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.c mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json,mixins.sponge.test.json superClassChanges=common.superclasschange -minecraftVersion=1.21.9-pre3 +minecraftVersion=1.21.9-pre4 recommendedVersion=0-SNAPSHOT org.gradle.dependency.verification.console=verbose From 4c7bd6d55330e1c3e5920afd8953cc669036b4c4 Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Sat, 27 Sep 2025 19:07:47 -0700 Subject: [PATCH 16/24] feat(minecraft): update to 1.21.9-rc1 See: https://minecraft.wiki/w/Java_Edition_1.21.9_Release_Candidate_1 --- gradle.properties | 2 +- gradle/verification-metadata.xml | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 41511f810c2..0203cf330be 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.c mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json,mixins.sponge.test.json superClassChanges=common.superclasschange -minecraftVersion=1.21.9-pre4 +minecraftVersion=1.21.9-rc1 recommendedVersion=0-SNAPSHOT org.gradle.dependency.verification.console=verbose diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 5ff83c7aa5f..df1a7205e1f 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -1533,6 +1533,14 @@ + + + + + + + + From af1f0b0bb7c9a8ca58df67f1718449f76e245103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ossi=20Erkkil=C3=A4?= <52257907+avaruus1@users.noreply.github.com> Date: Mon, 29 Sep 2025 02:33:46 +0300 Subject: [PATCH 17/24] Expose minecraft:blocks_attacks and minecraft:weapon (#4233) --- SpongeAPI | 2 +- .../provider/item/stack/ItemStackData.java | 53 +++++ .../item/stack/ShieldItemStackData.java | 206 +++++++++++++++++- .../SpongeShieldDamageReductionFactory.java | 36 +++ ...ieldDamageReductionMultiplyAddBuilder.java | 109 +++++++++ ...SpongeShieldItemDamageFunctionFactory.java | 36 +++ ...dItemDamageFunctionMultiplyAddBuilder.java | 76 +++++++ .../registry/SpongeBuilderProvider.java | 6 + .../registry/SpongeFactoryProvider.java | 6 + .../spongepowered/common/util/Constants.java | 1 + ...locksAttacks_DamageReductionMixin_API.java | 84 +++++++ .../BlocksAttacks_ItemDamageFunction_API.java | 67 ++++++ src/mixins/resources/mixins.sponge.api.json | 2 + .../common/data/key/KeysTest.java | 125 +++++++++++ 14 files changed, 804 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/spongepowered/common/item/shield/SpongeShieldDamageReductionFactory.java create mode 100644 src/main/java/org/spongepowered/common/item/shield/SpongeShieldDamageReductionMultiplyAddBuilder.java create mode 100644 src/main/java/org/spongepowered/common/item/shield/SpongeShieldItemDamageFunctionFactory.java create mode 100644 src/main/java/org/spongepowered/common/item/shield/SpongeShieldItemDamageFunctionMultiplyAddBuilder.java create mode 100644 src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/item/component/BlocksAttacks_DamageReductionMixin_API.java create mode 100644 src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/item/component/BlocksAttacks_ItemDamageFunction_API.java create mode 100644 src/test/java/org/spongepowered/common/data/key/KeysTest.java diff --git a/SpongeAPI b/SpongeAPI index 9b0d6786155..214a97c9174 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit 9b0d678615595bec00cf099af576c931cc044d48 +Subproject commit 214a97c9174a315b226bc716c77d7a4d7c7091d2 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 a9d1d4212fd..e4d0d005a1c 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 @@ -47,6 +47,7 @@ import net.minecraft.world.item.component.ItemLore; import net.minecraft.world.item.component.UseCooldown; import net.minecraft.world.item.component.UseRemainder; +import net.minecraft.world.item.component.Weapon; import net.minecraft.world.item.consume_effects.ConsumeEffect; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.Platform; @@ -65,6 +66,7 @@ import org.spongepowered.common.adventure.SpongeAdventure; import org.spongepowered.common.data.provider.DataProviderRegistrator; import org.spongepowered.common.item.util.ItemStackUtil; +import org.spongepowered.common.util.Constants; import java.util.List; import java.util.Optional; @@ -370,6 +372,57 @@ public static void register(final DataProviderRegistrator registrator) { .get(h -> (ResourceKey) (Object) h.get(DataComponents.TOOLTIP_STYLE)) .set((h, v) -> h.set(DataComponents.TOOLTIP_STYLE, (ResourceLocation) (Object) v)) .delete(h -> h.remove(DataComponents.TOOLTIP_STYLE)) + .create(Keys.WEAPON_DAMAGE_PER_ATTACK) + .get(h -> { + final @Nullable Weapon weapon = h.get(DataComponents.WEAPON); + if (weapon == null) { + return null; + } + return weapon.itemDamagePerAttack(); + }) + .set((h, v) -> { + final @Nullable Weapon weapon = h.get(DataComponents.WEAPON); + h.set(DataComponents.WEAPON, new Weapon(v, weapon == null ? 0 : weapon.disableBlockingForSeconds())); + }) + .delete(h -> { + final @Nullable Weapon weapon = h.get(DataComponents.WEAPON); + if (weapon == null) { + return; + } + if (weapon.disableBlockingForSeconds() == 0) { + h.remove(DataComponents.WEAPON); + } else { + h.set(DataComponents.WEAPON, new Weapon(0, weapon.disableBlockingForSeconds())); + } + }) + .create(Keys.DISABLE_SHIELD_TICKS) + .get(h -> { + final @Nullable Weapon weapon = h.get(DataComponents.WEAPON); + if (weapon == null) { + return null; + } + return Ticks.of(Math.round( + Constants.TickConversions.TICKS_PER_SECOND * weapon.disableBlockingForSeconds() + )); + }) + .set((h, v) -> { + final @Nullable Weapon weapon = h.get(DataComponents.WEAPON); + h.set(DataComponents.WEAPON, new Weapon( + weapon == null ? 0 : weapon.itemDamagePerAttack(), + v.ticks() / (float) Constants.TickConversions.TICKS_PER_SECOND + )); + }) + .delete(h -> { + final @Nullable Weapon weapon = h.get(DataComponents.WEAPON); + if (weapon == null) { + return; + } + if (weapon.itemDamagePerAttack() == 0) { + h.remove(DataComponents.WEAPON); + } else { + h.set(DataComponents.WEAPON, new Weapon(weapon.itemDamagePerAttack())); + } + }) ; } // @formatter:on diff --git a/src/main/java/org/spongepowered/common/data/provider/item/stack/ShieldItemStackData.java b/src/main/java/org/spongepowered/common/data/provider/item/stack/ShieldItemStackData.java index 9b499f8084f..d0438441f6e 100644 --- a/src/main/java/org/spongepowered/common/data/provider/item/stack/ShieldItemStackData.java +++ b/src/main/java/org/spongepowered/common/data/provider/item/stack/ShieldItemStackData.java @@ -24,15 +24,28 @@ */ package org.spongepowered.common.data.provider.item.stack; +import net.minecraft.core.Holder; import net.minecraft.core.component.DataComponents; -import net.minecraft.world.item.BannerItem; +import net.minecraft.sounds.SoundEvent; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.ShieldItem; +import net.minecraft.world.item.component.BlocksAttacks; import net.minecraft.world.level.block.entity.BannerPatternLayers; +import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.data.Keys; import org.spongepowered.api.data.meta.BannerPatternLayer; import org.spongepowered.api.data.type.DyeColor; +import org.spongepowered.api.data.type.ShieldDamageReduction; +import org.spongepowered.api.data.type.ShieldItemDamageFunction; +import org.spongepowered.api.effect.sound.SoundType; +import org.spongepowered.api.event.cause.entity.damage.DamageType; +import org.spongepowered.api.tag.Tag; +import org.spongepowered.api.util.Ticks; +import org.spongepowered.common.bridge.tags.TagBridge; import org.spongepowered.common.data.provider.DataProviderRegistrator; +import org.spongepowered.common.util.Constants; + +import java.util.List; +import java.util.Optional; public final class ShieldItemStackData { @@ -46,7 +59,6 @@ public static void register(final DataProviderRegistrator registrator) { .create(Keys.DYE_COLOR) .get(h -> (DyeColor) (Object) h.getOrDefault(DataComponents.BASE_COLOR, net.minecraft.world.item.DyeColor.WHITE)) .set((h, v) -> h.set(DataComponents.BASE_COLOR, (net.minecraft.world.item.DyeColor) (Object) v)) - .supports(h -> h.getItem() instanceof ShieldItem) .create(Keys.BANNER_PATTERN_LAYERS) .get(h -> h.getOrDefault(DataComponents.BANNER_PATTERNS, BannerPatternLayers.EMPTY).layers() .stream().map(BannerPatternLayer.class::cast).toList()) @@ -54,8 +66,194 @@ public static void register(final DataProviderRegistrator registrator) { h.set(DataComponents.BANNER_PATTERNS, new BannerPatternLayers(v.stream().map(BannerPatternLayers.Layer.class::cast).toList())); // TODO check setting banner base? Constants.TileEntity.Banner.BANNER_BASE / BannerPatternShapes.BASE }) - .supports(h -> h.getItem() instanceof ShieldItem || h.getItem() instanceof BannerItem); + .create(Keys.SHIELD_DEPLOY_TICKS) + .get(h -> { + final @Nullable BlocksAttacks blocksAttacks = h.get(DataComponents.BLOCKS_ATTACKS); + if (blocksAttacks == null) { + return null; + } + return Ticks.of((long) (Constants.TickConversions.TICKS_PER_SECOND * blocksAttacks.blockDelaySeconds())); + }) + .set((h, v) -> { + final @Nullable BlocksAttacks blocksAttacks = h.getOrDefault(DataComponents.BLOCKS_ATTACKS, BLOCKS_ATTACKS_DEFAULTS); + h.set(DataComponents.BLOCKS_ATTACKS, new BlocksAttacks( + v.ticks() / (float) Constants.TickConversions.TICKS_PER_SECOND, + blocksAttacks.disableCooldownScale(), + blocksAttacks.damageReductions(), + blocksAttacks.itemDamage(), + blocksAttacks.bypassedBy(), + blocksAttacks.blockSound(), + blocksAttacks.disableSound() + )); + }) + .create(Keys.DISABLE_SHIELD_TICKS_SCALE) + .get(h -> { + final @Nullable BlocksAttacks blocksAttacks = h.get(DataComponents.BLOCKS_ATTACKS); + if (blocksAttacks == null) { + return null; + } + return (double) blocksAttacks.disableCooldownScale(); + }) + .set((h, v) -> { + final @Nullable BlocksAttacks blocksAttacks = h.getOrDefault(DataComponents.BLOCKS_ATTACKS, BLOCKS_ATTACKS_DEFAULTS); + h.set(DataComponents.BLOCKS_ATTACKS, new BlocksAttacks( + blocksAttacks.blockDelaySeconds(), + v.floatValue(), + blocksAttacks.damageReductions(), + blocksAttacks.itemDamage(), + blocksAttacks.bypassedBy(), + blocksAttacks.blockSound(), + blocksAttacks.disableSound() + )); + }) + .create(Keys.SHIELD_DAMAGE_REDUCTIONS) + .get(h -> { + final @Nullable BlocksAttacks blocksAttacks = h.get(DataComponents.BLOCKS_ATTACKS); + if (blocksAttacks == null) { + return null; + } + return (List>) (Object) List.copyOf(blocksAttacks.damageReductions()); + }) + .set((h, v) -> { + final @Nullable BlocksAttacks blocksAttacks = h.getOrDefault(DataComponents.BLOCKS_ATTACKS, BLOCKS_ATTACKS_DEFAULTS); + h.set(DataComponents.BLOCKS_ATTACKS, new BlocksAttacks( + blocksAttacks.blockDelaySeconds(), + blocksAttacks.disableCooldownScale(), + (List) (Object) List.copyOf(v), + blocksAttacks.itemDamage(), + blocksAttacks.bypassedBy(), + blocksAttacks.blockSound(), + blocksAttacks.disableSound() + )); + }) + .create(Keys.SHIELD_ITEM_DAMAGE_FUNCTION) + .get(h -> { + final @Nullable BlocksAttacks blocksAttacks = h.get(DataComponents.BLOCKS_ATTACKS); + if (blocksAttacks == null) { + return null; + } + return (ShieldItemDamageFunction) (Object) blocksAttacks.itemDamage(); + }) + .set((h, v) -> { + final @Nullable BlocksAttacks blocksAttacks = h.getOrDefault(DataComponents.BLOCKS_ATTACKS, BLOCKS_ATTACKS_DEFAULTS); + h.set(DataComponents.BLOCKS_ATTACKS, new BlocksAttacks( + blocksAttacks.blockDelaySeconds(), + blocksAttacks.disableCooldownScale(), + blocksAttacks.damageReductions(), + (BlocksAttacks.ItemDamageFunction) (Object) v, + blocksAttacks.bypassedBy(), + blocksAttacks.blockSound(), + blocksAttacks.disableSound() + )); + }) + .create(Keys.BYPASS_DAMAGE_TAG) + .get(h -> { + final @Nullable BlocksAttacks blocksAttacks = h.get(DataComponents.BLOCKS_ATTACKS); + if (blocksAttacks == null || blocksAttacks.bypassedBy().isEmpty()) { + return null; + } + return (Tag) (Object) blocksAttacks.bypassedBy().get(); + }) + .set((h, v) -> { + final @Nullable BlocksAttacks blocksAttacks = h.getOrDefault(DataComponents.BLOCKS_ATTACKS, BLOCKS_ATTACKS_DEFAULTS); + h.set(DataComponents.BLOCKS_ATTACKS, new BlocksAttacks( + blocksAttacks.blockDelaySeconds(), + blocksAttacks.disableCooldownScale(), + blocksAttacks.damageReductions(), + blocksAttacks.itemDamage(), + Optional.of(((TagBridge) v).bridge$asVanillaTag()), + blocksAttacks.blockSound(), + blocksAttacks.disableSound() + )); + }) + .delete(h -> { + final @Nullable BlocksAttacks blocksAttacks = h.getOrDefault(DataComponents.BLOCKS_ATTACKS, BLOCKS_ATTACKS_DEFAULTS); + h.set(DataComponents.BLOCKS_ATTACKS, new BlocksAttacks( + blocksAttacks.blockDelaySeconds(), + blocksAttacks.disableCooldownScale(), + blocksAttacks.damageReductions(), + blocksAttacks.itemDamage(), + Optional.empty(), + blocksAttacks.blockSound(), + blocksAttacks.disableSound() + )); + }) + .create(Keys.SHIELD_BLOCK_SOUND) + .get(h -> { + final @Nullable BlocksAttacks blocksAttacks = h.get(DataComponents.BLOCKS_ATTACKS); + if (blocksAttacks == null || blocksAttacks.blockSound().isEmpty()) { + return null; + } + return (SoundType) (Object) blocksAttacks.blockSound().get().value(); + }) + .set((h, v) -> { + final @Nullable BlocksAttacks blocksAttacks = h.getOrDefault(DataComponents.BLOCKS_ATTACKS, BLOCKS_ATTACKS_DEFAULTS); + h.set(DataComponents.BLOCKS_ATTACKS, new BlocksAttacks( + blocksAttacks.blockDelaySeconds(), + blocksAttacks.disableCooldownScale(), + blocksAttacks.damageReductions(), + blocksAttacks.itemDamage(), + blocksAttacks.bypassedBy(), + Optional.of(Holder.direct((SoundEvent) (Object) v)), + blocksAttacks.disableSound() + )); + }) + .delete(h -> { + final @Nullable BlocksAttacks blocksAttacks = h.getOrDefault(DataComponents.BLOCKS_ATTACKS, BLOCKS_ATTACKS_DEFAULTS); + h.set(DataComponents.BLOCKS_ATTACKS, new BlocksAttacks( + blocksAttacks.blockDelaySeconds(), + blocksAttacks.disableCooldownScale(), + blocksAttacks.damageReductions(), + blocksAttacks.itemDamage(), + blocksAttacks.bypassedBy(), + Optional.empty(), + blocksAttacks.disableSound() + )); + }) + .create(Keys.SHIELD_DISABLE_SOUND) + .get(h -> { + final @Nullable BlocksAttacks blocksAttacks = h.get(DataComponents.BLOCKS_ATTACKS); + if (blocksAttacks == null || blocksAttacks.disableSound().isEmpty()) { + return null; + } + return (SoundType) (Object) blocksAttacks.disableSound().get().value(); + }) + .set((h, v) -> { + final @Nullable BlocksAttacks blocksAttacks = h.getOrDefault(DataComponents.BLOCKS_ATTACKS, BLOCKS_ATTACKS_DEFAULTS); + h.set(DataComponents.BLOCKS_ATTACKS, new BlocksAttacks( + blocksAttacks.blockDelaySeconds(), + blocksAttacks.disableCooldownScale(), + blocksAttacks.damageReductions(), + blocksAttacks.itemDamage(), + blocksAttacks.bypassedBy(), + blocksAttacks.blockSound(), + Optional.of(Holder.direct((SoundEvent) (Object) v)) + )); + }) + .delete(h -> { + final @Nullable BlocksAttacks blocksAttacks = h.getOrDefault(DataComponents.BLOCKS_ATTACKS, BLOCKS_ATTACKS_DEFAULTS); + h.set(DataComponents.BLOCKS_ATTACKS, new BlocksAttacks( + blocksAttacks.blockDelaySeconds(), + blocksAttacks.disableCooldownScale(), + blocksAttacks.damageReductions(), + blocksAttacks.itemDamage(), + blocksAttacks.bypassedBy(), + blocksAttacks.blockSound(), + Optional.empty() + )); + }) + ; } // @formatter:on + private static final BlocksAttacks BLOCKS_ATTACKS_DEFAULTS = new BlocksAttacks( + 0, + 1, + List.of(), + BlocksAttacks.ItemDamageFunction.DEFAULT, + Optional.empty(), + Optional.empty(), + Optional.empty() + ); + } diff --git a/src/main/java/org/spongepowered/common/item/shield/SpongeShieldDamageReductionFactory.java b/src/main/java/org/spongepowered/common/item/shield/SpongeShieldDamageReductionFactory.java new file mode 100644 index 00000000000..719ab097f17 --- /dev/null +++ b/src/main/java/org/spongepowered/common/item/shield/SpongeShieldDamageReductionFactory.java @@ -0,0 +1,36 @@ +/* + * 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.item.shield; + +import org.spongepowered.api.data.type.ShieldDamageReduction; + +public final class SpongeShieldDamageReductionFactory implements ShieldDamageReduction.Factory { + + @Override + public ShieldDamageReduction create(final ShieldDamageReduction.MultiplyAdd config) { + return (ShieldDamageReduction) config; + } + +} diff --git a/src/main/java/org/spongepowered/common/item/shield/SpongeShieldDamageReductionMultiplyAddBuilder.java b/src/main/java/org/spongepowered/common/item/shield/SpongeShieldDamageReductionMultiplyAddBuilder.java new file mode 100644 index 00000000000..194978f163d --- /dev/null +++ b/src/main/java/org/spongepowered/common/item/shield/SpongeShieldDamageReductionMultiplyAddBuilder.java @@ -0,0 +1,109 @@ +/* + * 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.item.shield; + +import net.minecraft.core.HolderSet; +import net.minecraft.core.Registry; +import net.minecraft.world.item.component.BlocksAttacks; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.data.type.ShieldDamageReduction; +import org.spongepowered.api.event.cause.entity.damage.DamageType; +import org.spongepowered.api.registry.RegistryTypes; +import org.spongepowered.api.tag.Tag; +import org.spongepowered.common.bridge.tags.TagBridge; +import org.spongepowered.common.util.Preconditions; + +import java.util.Optional; +import java.util.Set; + +public final class SpongeShieldDamageReductionMultiplyAddBuilder implements ShieldDamageReduction.MultiplyAdd.Builder { + private HolderSet damageTypes; + private Double horizontalBlockingAngle; + private double base = 0; + private double factor = 0; + + @Override + public ShieldDamageReduction.MultiplyAdd.Builder damageTypes(final Set damageTypes) { + final Registry registry = (Registry) Sponge.server().registry(RegistryTypes.DAMAGE_TYPE); + + this.damageTypes = HolderSet.direct(damageTypes.stream() + .map(dt -> registry.wrapAsHolder((net.minecraft.world.damagesource.DamageType) (Object) dt)) + .toList()); + + return this; + } + + @Override + public ShieldDamageReduction.MultiplyAdd.Builder damageTypes(final Tag tag) { + final Registry registry = (Registry) Sponge.server().registry(RegistryTypes.DAMAGE_TYPE); + final var vanillaTag = ((TagBridge) tag).bridge$asVanillaTag(); + this.damageTypes = registry.getOrThrow(vanillaTag); + + return this; + } + + @Override + public ShieldDamageReduction.MultiplyAdd.Builder horizontalBlockingAngle(final double angle) { + Preconditions.checkArgument(angle > 0, "angle must be positive"); + this.horizontalBlockingAngle = angle; + + return this; + } + + @Override + public ShieldDamageReduction.MultiplyAdd.Builder constantReduction(final double constant) { + this.base = constant; + + return this; + } + + @Override + public ShieldDamageReduction.MultiplyAdd.Builder fractionalReduction(final double fraction) { + this.factor = fraction; + + return this; + } + + @Override + public ShieldDamageReduction.MultiplyAdd build() { + return (ShieldDamageReduction.MultiplyAdd) (Object) new BlocksAttacks.DamageReduction( + this.horizontalBlockingAngle != null ? this.horizontalBlockingAngle.floatValue() : 90, + Optional.ofNullable(this.damageTypes), + (float) this.base, + (float) this.factor + ); + } + + @Override + public ShieldDamageReduction.MultiplyAdd.Builder reset() { + this.damageTypes = null; + this.horizontalBlockingAngle = null; + this.base = 0; + this.factor = 0; + + return this; + } + +} diff --git a/src/main/java/org/spongepowered/common/item/shield/SpongeShieldItemDamageFunctionFactory.java b/src/main/java/org/spongepowered/common/item/shield/SpongeShieldItemDamageFunctionFactory.java new file mode 100644 index 00000000000..6174a5cb8c1 --- /dev/null +++ b/src/main/java/org/spongepowered/common/item/shield/SpongeShieldItemDamageFunctionFactory.java @@ -0,0 +1,36 @@ +/* + * 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.item.shield; + +import org.spongepowered.api.data.type.ShieldItemDamageFunction; + +public final class SpongeShieldItemDamageFunctionFactory implements ShieldItemDamageFunction.Factory { + + @Override + public ShieldItemDamageFunction create(final ShieldItemDamageFunction.MultiplyAdd config) { + return (ShieldItemDamageFunction) config; + } + +} diff --git a/src/main/java/org/spongepowered/common/item/shield/SpongeShieldItemDamageFunctionMultiplyAddBuilder.java b/src/main/java/org/spongepowered/common/item/shield/SpongeShieldItemDamageFunctionMultiplyAddBuilder.java new file mode 100644 index 00000000000..cb241ad33f6 --- /dev/null +++ b/src/main/java/org/spongepowered/common/item/shield/SpongeShieldItemDamageFunctionMultiplyAddBuilder.java @@ -0,0 +1,76 @@ +/* + * 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.item.shield; + +import net.minecraft.world.item.component.BlocksAttacks; +import org.spongepowered.api.data.type.ShieldItemDamageFunction; +import org.spongepowered.common.util.Preconditions; + +public final class SpongeShieldItemDamageFunctionMultiplyAddBuilder implements ShieldItemDamageFunction.MultiplyAdd.Builder { + private double minAttackDamage = 0; + private double constantDamage = 0; + private double fractionalDamage = 0; + + @Override + public ShieldItemDamageFunction.MultiplyAdd.Builder minAttackDamage(final double minDamage) { + Preconditions.checkArgument(minDamage >= 0, "minAttackDamage must not be negative"); + this.minAttackDamage = minDamage; + + return this; + } + + @Override + public ShieldItemDamageFunction.MultiplyAdd.Builder constantDamage(final double constantDamage) { + this.constantDamage = constantDamage; + + return this; + } + + @Override + public ShieldItemDamageFunction.MultiplyAdd.Builder fractionalDamage(final double fractionalDamage) { + this.fractionalDamage = fractionalDamage; + + return this; + } + + @Override + public ShieldItemDamageFunction.MultiplyAdd build() { + return (ShieldItemDamageFunction.MultiplyAdd) (Object) new BlocksAttacks.ItemDamageFunction( + (float) this.minAttackDamage, + (float) this.constantDamage, + (float) this.fractionalDamage + ); + } + + @Override + public ShieldItemDamageFunction.MultiplyAdd.Builder reset() { + this.minAttackDamage = 0; + this.constantDamage = 0; + this.fractionalDamage = 0; + + return this; + } + +} diff --git a/src/main/java/org/spongepowered/common/registry/SpongeBuilderProvider.java b/src/main/java/org/spongepowered/common/registry/SpongeBuilderProvider.java index 821ca0dcb09..3ddcd3873f3 100644 --- a/src/main/java/org/spongepowered/common/registry/SpongeBuilderProvider.java +++ b/src/main/java/org/spongepowered/common/registry/SpongeBuilderProvider.java @@ -51,6 +51,8 @@ import org.spongepowered.api.data.meta.BannerPatternLayer; import org.spongepowered.api.data.persistence.DataStore; import org.spongepowered.api.data.type.ArtType; +import org.spongepowered.api.data.type.ShieldDamageReduction; +import org.spongepowered.api.data.type.ShieldItemDamageFunction; import org.spongepowered.api.effect.particle.ParticleEffect; import org.spongepowered.api.effect.potion.PotionEffect; import org.spongepowered.api.effect.sound.SoundType; @@ -204,6 +206,8 @@ import org.spongepowered.common.item.recipe.ingredient.SpongeIngredientBuilder; import org.spongepowered.common.item.recipe.smithing.SpongeSmithingRecipeBuilder; import org.spongepowered.common.item.recipe.stonecutting.SpongeStoneCutterRecipeBuilder; +import org.spongepowered.common.item.shield.SpongeShieldDamageReductionMultiplyAddBuilder; +import org.spongepowered.common.item.shield.SpongeShieldItemDamageFunctionMultiplyAddBuilder; import org.spongepowered.common.map.canvas.SpongeMapCanvasBuilder; import org.spongepowered.common.map.color.SpongeMapColorBuilder; import org.spongepowered.common.map.decoration.SpongeMapDecorationBuilder; @@ -395,6 +399,8 @@ public void registerDefaultBuilders() { .register(PortalLogic.Builder.class, SpongePortalLogicBuilder::new) .register(ServerWorldProperties.LoadOptions.Builder.class, SpongeServerWorldPropertiesLoadOptions.BuilderImpl::new) .register(WorldArchetype.Builder.class, SpongeWorldArchetype.BuilderImpl::new) + .register(ShieldDamageReduction.MultiplyAdd.Builder.class, SpongeShieldDamageReductionMultiplyAddBuilder::new) + .register(ShieldItemDamageFunction.MultiplyAdd.Builder.class, SpongeShieldItemDamageFunctionMultiplyAddBuilder::new) ; } } diff --git a/src/main/java/org/spongepowered/common/registry/SpongeFactoryProvider.java b/src/main/java/org/spongepowered/common/registry/SpongeFactoryProvider.java index b39affb0bce..bdebce0d637 100644 --- a/src/main/java/org/spongepowered/common/registry/SpongeFactoryProvider.java +++ b/src/main/java/org/spongepowered/common/registry/SpongeFactoryProvider.java @@ -42,6 +42,8 @@ import org.spongepowered.api.command.selector.Selector; import org.spongepowered.api.data.DataManipulator; import org.spongepowered.api.data.type.ItemAction; +import org.spongepowered.api.data.type.ShieldDamageReduction; +import org.spongepowered.api.data.type.ShieldItemDamageFunction; import org.spongepowered.api.data.type.ToolRule; import org.spongepowered.api.data.value.Value; import org.spongepowered.api.effect.ForwardingViewer; @@ -133,6 +135,8 @@ import org.spongepowered.common.item.SpongeToolRuleFactory; import org.spongepowered.common.item.recipe.SpongeRecipeInputFactory; import org.spongepowered.common.item.recipe.smithing.SpongeArmorTrimFactory; +import org.spongepowered.common.item.shield.SpongeShieldDamageReductionFactory; +import org.spongepowered.common.item.shield.SpongeShieldItemDamageFunctionFactory; import org.spongepowered.common.item.util.SpongeItemStackComparatorFactory; import org.spongepowered.common.network.channel.SpongeChannelExceptionHandlerFactory; import org.spongepowered.common.network.status.SpongeFavicon; @@ -292,6 +296,8 @@ public void registerDefaultFactories() { .registerFactory(RecipeInput.Factory.class, new SpongeRecipeInputFactory()) .registerFactory(ArmorTrim.Factory.class, new SpongeArmorTrimFactory()) .registerFactory(RegistryRegistrationSet.Factory.class, new SpongeRegistryRegistrationSet.FactoryImpl()) + .registerFactory(ShieldDamageReduction.Factory.class, new SpongeShieldDamageReductionFactory()) + .registerFactory(ShieldItemDamageFunction.Factory.class, new SpongeShieldItemDamageFunctionFactory()) ; } } diff --git a/src/main/java/org/spongepowered/common/util/Constants.java b/src/main/java/org/spongepowered/common/util/Constants.java index db3dbb7b1f8..eb2601246ba 100644 --- a/src/main/java/org/spongepowered/common/util/Constants.java +++ b/src/main/java/org/spongepowered/common/util/Constants.java @@ -1539,6 +1539,7 @@ public static final class KeyValueMatcher { public static final class TickConversions { public static final int TICK_DURATION_MS = 50; + public static final int TICKS_PER_SECOND = 1000 / TICK_DURATION_MS; public static final Duration EFFECTIVE_MINIMUM_DURATION = Duration.ofMillis(TickConversions.TICK_DURATION_MS); public static final int MINECRAFT_DAY_TICKS = 24000; diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/item/component/BlocksAttacks_DamageReductionMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/item/component/BlocksAttacks_DamageReductionMixin_API.java new file mode 100644 index 00000000000..248bc1f1910 --- /dev/null +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/item/component/BlocksAttacks_DamageReductionMixin_API.java @@ -0,0 +1,84 @@ +/* + * 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.mixin.api.minecraft.world.item.component; + +import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; +import net.minecraft.world.item.component.BlocksAttacks; +import org.spongepowered.api.data.type.ShieldDamageReduction; +import org.spongepowered.api.event.cause.entity.damage.DamageType; +import org.spongepowered.api.event.cause.entity.damage.source.DamageSource; +import org.spongepowered.asm.mixin.*; + +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +@Mixin(BlocksAttacks.DamageReduction.class) +@Implements({ + @Interface(iface = ShieldDamageReduction.class, prefix = "shielddamagereduction$"), + @Interface(iface = ShieldDamageReduction.MultiplyAdd.class, prefix = "shielddamagereductionmultiplyadd$") +}) +public abstract class BlocksAttacks_DamageReductionMixin_API implements ShieldDamageReduction, ShieldDamageReduction.MultiplyAdd { + + @Shadow @Final private Optional> type; + @Shadow @Final private float base; + @Shadow @Final private float factor; + @Shadow @Final private float horizontalBlockingAngle; + + @Shadow public abstract float shadow$resolve(net.minecraft.world.damagesource.DamageSource $$0, float $$1, double $$2); + + @Override + public MultiplyAdd configuration() { + return this; + } + + public double shielddamagereduction$resolve(final DamageSource source, final double damage, final double angle) { + return this.shadow$resolve((net.minecraft.world.damagesource.DamageSource) source, (float) damage, angle); + } + + @Override + public Optional> damageTypes() { + return this.type.map(set -> set.stream() + .map(Holder::value) + .map(DamageType.class::cast) + .collect(Collectors.toSet())); + } + + public double shielddamagereductionmultiplyadd$horizontalBlockingAngle() { + return this.horizontalBlockingAngle; + } + + @Override + public double constantReduction() { + return this.base; + } + + @Override + public double fractionalReduction() { + return this.factor; + } + +} diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/item/component/BlocksAttacks_ItemDamageFunction_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/item/component/BlocksAttacks_ItemDamageFunction_API.java new file mode 100644 index 00000000000..558458c2460 --- /dev/null +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/item/component/BlocksAttacks_ItemDamageFunction_API.java @@ -0,0 +1,67 @@ +/* + * 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.mixin.api.minecraft.world.item.component; + +import net.minecraft.world.item.component.BlocksAttacks; +import org.spongepowered.api.data.type.ShieldItemDamageFunction; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(BlocksAttacks.ItemDamageFunction.class) +public abstract class BlocksAttacks_ItemDamageFunction_API implements ShieldItemDamageFunction.MultiplyAdd, ShieldItemDamageFunction { + + @Shadow @Final private float threshold; + @Shadow @Final private float base; + @Shadow @Final private float factor; + + @Shadow public abstract int shadow$apply(float $$0); + + @Override + public MultiplyAdd configuration() { + return this; + } + + @Override + public double resolve(final double damage) { + return this.shadow$apply((float) damage); + } + + @Override + public double minAttackDamage() { + return this.threshold; + } + + @Override + public double constantDamage() { + return this.base; + } + + @Override + public double fractionalDamage() { + return this.factor; + } + +} diff --git a/src/mixins/resources/mixins.sponge.api.json b/src/mixins/resources/mixins.sponge.api.json index c0189a5990e..840a6f902da 100644 --- a/src/mixins/resources/mixins.sponge.api.json +++ b/src/mixins/resources/mixins.sponge.api.json @@ -333,6 +333,8 @@ "minecraft.world.item.RarityMixin_API", "minecraft.world.item.ToolMaterialMixin_API", "minecraft.world.item.alchemy.PotionMixin_API", + "minecraft.world.item.component.BlocksAttacks_DamageReductionMixin_API", + "minecraft.world.item.component.BlocksAttacks_ItemDamageFunction_API", "minecraft.world.item.component.FireworkExplosionMixin_API", "minecraft.world.item.component.Tool_RuleMixin_API", "minecraft.world.item.consume_effects.ApplyStatusEffectsConsumeEffectMixin_API", diff --git a/src/test/java/org/spongepowered/common/data/key/KeysTest.java b/src/test/java/org/spongepowered/common/data/key/KeysTest.java new file mode 100644 index 00000000000..5a7f8a4ac9f --- /dev/null +++ b/src/test/java/org/spongepowered/common/data/key/KeysTest.java @@ -0,0 +1,125 @@ +/* + * 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.data.key; + +import io.leangen.geantyref.GenericTypeReflector; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.spongepowered.api.ResourceKeyed; +import org.spongepowered.api.data.Key; +import org.spongepowered.api.data.Keys; +import org.spongepowered.api.data.type.ShieldDamageReduction; +import org.spongepowered.api.data.type.ShieldItemDamageFunction; +import org.spongepowered.api.data.value.Value; +import org.spongepowered.api.effect.sound.SoundTypes; +import org.spongepowered.api.event.cause.entity.damage.DamageTypes; +import org.spongepowered.api.item.ItemTypes; +import org.spongepowered.api.item.inventory.ItemStack; +import org.spongepowered.api.tag.DamageTypeTags; +import org.spongepowered.api.util.Ticks; + +import java.util.List; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Stream; + +public class KeysTest { + + private static Stream testSingleKeys() { + return Stream.of( + Arguments.of(Keys.WEAPON_DAMAGE_PER_ATTACK, 5), + Arguments.of(Keys.DISABLE_SHIELD_TICKS, Ticks.of(10)), + Arguments.of(Keys.SHIELD_DEPLOY_TICKS, Ticks.of(15)), + Arguments.of(Keys.DISABLE_SHIELD_TICKS_SCALE, 2.5), + Arguments.of(Keys.SHIELD_DAMAGE_REDUCTIONS, List.of(ShieldDamageReduction.of(ShieldDamageReduction.MultiplyAdd.builder() + .horizontalBlockingAngle(45) + .constantReduction(2) + .fractionalReduction(0.5) + .damageTypes(Set.of(DamageTypes.ARROW.get(), DamageTypes.PLAYER_ATTACK.get())) + .build()))), + Arguments.of(Keys.SHIELD_ITEM_DAMAGE_FUNCTION, ShieldItemDamageFunction.of(ShieldItemDamageFunction.MultiplyAdd.builder() + .constantDamage(5) + .fractionalDamage(2) + .minAttackDamage(2.5) + .build())), + Arguments.of(Keys.SHIELD_BLOCK_SOUND, SoundTypes.ENTITY_SHULKER_HURT.get()), + Arguments.of(Keys.SHIELD_DISABLE_SOUND, SoundTypes.ENTITY_ENDER_DRAGON_DEATH.get()) + ); + } + + @MethodSource + @ParameterizedTest + void testSingleKeys(Key k, Object value) { + testSingleKeyUnchecked(k, value); + } + + @Test + void testBypassDamageTag() { + testSingleKey(Keys.BYPASS_DAMAGE_TAG, DamageTypeTags.BYPASSES_ARMOR, ResourceKeyed::key); + } + + @Test + void testAllWeaponKeys() { + final var stack = ItemStack.builder() + .itemType(ItemTypes.DIAMOND_SWORD) + .add(Keys.WEAPON_DAMAGE_PER_ATTACK, 5) + .add(Keys.DISABLE_SHIELD_TICKS, Ticks.of(5)) + .build(); + + Assertions.assertEquals(5, stack.require(Keys.WEAPON_DAMAGE_PER_ATTACK)); + Assertions.assertEquals(Ticks.of(5), stack.require(Keys.DISABLE_SHIELD_TICKS)); + + stack.remove(Keys.DISABLE_SHIELD_TICKS); + Assertions.assertEquals(5, stack.require(Keys.WEAPON_DAMAGE_PER_ATTACK)); + + stack.remove(Keys.WEAPON_DAMAGE_PER_ATTACK); + + Assertions.assertNull(stack.getOrNull(Keys.WEAPON_DAMAGE_PER_ATTACK)); + Assertions.assertNull(stack.getOrNull(Keys.DISABLE_SHIELD_TICKS)); + } + + @SuppressWarnings("unchecked") + private static > void testSingleKeyUnchecked(Key k, Object value) { + if (!GenericTypeReflector.isSuperType(k.elementType(), value.getClass())) { + throw new IllegalArgumentException("Invalid value type for key " + k.key() + ": " + value.getClass().getName()); + } + + testSingleKey((Key) k, (T) value, a -> a); + } + + private static > void testSingleKey(Key k, T value, Function equalityExtractor) { + final var stack = ItemStack.builder() + .itemType(ItemTypes.DIAMOND_SWORD) + .add(k, value) + .build(); + + Assertions.assertEquals(equalityExtractor.apply(value), equalityExtractor.apply(stack.require(k)), () -> "retrieved value is not equal " + + "to the original for " + k.key().asString()); + } + +} From bae62c0f793c2bc6d4a2cee9135a5a12787be647 Mon Sep 17 00:00:00 2001 From: aromaa Date: Mon, 29 Sep 2025 22:04:02 +0300 Subject: [PATCH 18/24] Add BlockEntityType to DataManager registryTypeMap --- .../java/org/spongepowered/common/data/SpongeDataManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/spongepowered/common/data/SpongeDataManager.java b/src/main/java/org/spongepowered/common/data/SpongeDataManager.java index b1d84c2ef13..1173da06bcd 100644 --- a/src/main/java/org/spongepowered/common/data/SpongeDataManager.java +++ b/src/main/java/org/spongepowered/common/data/SpongeDataManager.java @@ -35,6 +35,7 @@ import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockState; import org.spongepowered.api.block.entity.BlockEntityArchetype; +import org.spongepowered.api.block.entity.BlockEntityType; import org.spongepowered.api.data.DataHolder; import org.spongepowered.api.data.DataHolderBuilder; import org.spongepowered.api.data.DataManager; @@ -434,6 +435,7 @@ public Optional> findRegistryTypeFor(Class type) { this.registryTypeMap.put(ParticleType.class, RegistryTypes.PARTICLE_TYPE); this.registryTypeMap.put(ParticleOption.class, RegistryTypes.PARTICLE_OPTION); this.registryTypeMap.put(PotionEffectType.class, RegistryTypes.POTION_EFFECT_TYPE); + this.registryTypeMap.put(BlockEntityType.class, RegistryTypes.BLOCK_ENTITY_TYPE); // TODO add all RegistryTypes that we have global registries for // there needs to be a better way to do this } From 8e990e9630c5357b9aae6f900e63641e1d87c44d Mon Sep 17 00:00:00 2001 From: aromaa Date: Mon, 29 Sep 2025 22:05:07 +0300 Subject: [PATCH 19/24] Fix createEntity(DataContainer) --- .../common/mixin/api/minecraft/world/level/LevelMixin_API.java | 2 +- .../spongepowered/common/mixin/core/world/level/LevelMixin.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/LevelMixin_API.java b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/LevelMixin_API.java index 71e7937a942..9ab5e4ac068 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/LevelMixin_API.java +++ b/src/mixins/java/org/spongepowered/common/mixin/api/minecraft/world/level/LevelMixin_API.java @@ -311,7 +311,7 @@ public E createEntityNaturally(f @Override public Optional createEntity(final DataContainer container) { - return ((LevelBridge) this).bridge$createEntity(container, null, null); + return Optional.ofNullable(((LevelBridge) this).bridge$createEntity(container, null, null)); } @Override diff --git a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/LevelMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/LevelMixin.java index f84890c3743..4111e1b81e0 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/core/world/level/LevelMixin.java +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/LevelMixin.java @@ -158,7 +158,7 @@ public abstract class LevelMixin implements LevelBridge, LevelAccessor { scale = null; } - final Entity createdEntity = this.bridge$createEntity(type, position, false); + final Entity createdEntity = this.bridge$createEntity(type, proposedPosition, false); dataContainer.getView(Constants.Sponge.UNSAFE_NBT) .map(NBTTranslator.INSTANCE::translate) .ifPresent(x -> { From 13d5b1580a405923d64fa20b3ec4169480ad9034 Mon Sep 17 00:00:00 2001 From: aromaa Date: Mon, 29 Sep 2025 22:10:01 +0300 Subject: [PATCH 20/24] Add unit test for custom Data API --- .../common/data/DataHolderTest.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/test/java/org/spongepowered/common/data/DataHolderTest.java diff --git a/src/test/java/org/spongepowered/common/data/DataHolderTest.java b/src/test/java/org/spongepowered/common/data/DataHolderTest.java new file mode 100644 index 00000000000..0e568400210 --- /dev/null +++ b/src/test/java/org/spongepowered/common/data/DataHolderTest.java @@ -0,0 +1,85 @@ +package data; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.animal.Cat; +import net.minecraft.world.level.Level; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.spongepowered.api.ResourceKey; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.block.BlockTypes; +import org.spongepowered.api.block.entity.BlockEntity; +import org.spongepowered.api.block.entity.BlockEntityArchetype; +import org.spongepowered.api.block.entity.BlockEntityType; +import org.spongepowered.api.block.entity.BlockEntityTypes; +import org.spongepowered.api.data.*; +import org.spongepowered.api.data.persistence.DataContainer; +import org.spongepowered.api.data.persistence.DataQuery; +import org.spongepowered.api.data.persistence.DataSerializable; +import org.spongepowered.api.data.value.Value; +import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.entity.EntityTypes; +import org.spongepowered.api.item.ItemTypes; +import org.spongepowered.api.item.inventory.ItemStack; +import org.spongepowered.api.world.DefaultWorldKeys; +import org.spongepowered.api.world.chunk.WorldChunk; +import org.spongepowered.api.world.server.ServerWorld; +import org.spongepowered.api.world.server.storage.ServerWorldProperties; +import org.spongepowered.common.data.SpongeDataManager; +import org.spongepowered.common.data.SpongeDataRegistration; +import org.spongepowered.common.util.Constants; +import org.spongepowered.math.vector.Vector3d; + +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Stream; + +public class DataHolderTest { + + private static final Key> STRING_KEY = Key.from(ResourceKey.of("test", "string"), String.class); + + static { + SpongeDataManager.INSTANCE.registerCustomDataRegistration((SpongeDataRegistration) DataRegistration.of(DataHolderTest.STRING_KEY, ItemStack.class, BlockEntity.class, Entity.class, WorldChunk.class, ServerWorldProperties.class)); + } + + public static Stream testEntity() { + final ServerWorld world = Sponge.server().worldManager().world(DefaultWorldKeys.DEFAULT).get(); + + return Stream.of( + DataHolderTest.testEntityArguments(() -> ItemStack.of(ItemTypes.DIAMOND), c -> ItemStack.builder().fromContainer(c).build()), + DataHolderTest.testEntityArguments(() -> BlockEntityArchetype.builder().blockEntity(BlockEntityTypes.CHEST).state(BlockTypes.CHEST.get().defaultState()).build(), c -> BlockEntityArchetype.builder().build(c).orElseThrow()), + DataHolderTest.testEntityArguments(() -> world.createEntity(EntityTypes.CAT, Vector3d.ZERO), c -> world.createEntity(c).orElseThrow()) + ); + } + + private static Arguments testEntityArguments(final Supplier supplier, final Function function) { + return Arguments.of(supplier, function); + } + + @ParameterizedTest + @MethodSource + public void testEntity(final Supplier supplier, final Function function) { + final var input = "test" + System.currentTimeMillis(); + + final T holder = supplier.get(); + final var offerResult = holder.offer(DataHolderTest.STRING_KEY, input); + + Assertions.assertEquals(DataTransactionResult.successResult(Value.immutableOf(DataHolderTest.STRING_KEY, input)), offerResult); + Assertions.assertEquals(Optional.of(input), holder.get(DataHolderTest.STRING_KEY)); + + final DataContainer originalContainer = holder.toContainer(); + + final T copy = function.apply(originalContainer); + + final DataContainer copyContainer = copy.toContainer(); + + originalContainer.remove(Constants.Sponge.UNSAFE_NBT.then(Constants.Entity.ENTITY_UUID)); + copyContainer.remove(Constants.Sponge.UNSAFE_NBT.then(Constants.Entity.ENTITY_UUID)); + + Assertions.assertEquals(originalContainer, copyContainer); + } +} From c4b7a1a1964c32a2568e3e4745e2690907a46cf4 Mon Sep 17 00:00:00 2001 From: aromaa Date: Mon, 29 Sep 2025 22:34:26 +0300 Subject: [PATCH 21/24] spotlessApply --- .../common/data/DataHolderTest.java | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/test/java/org/spongepowered/common/data/DataHolderTest.java b/src/test/java/org/spongepowered/common/data/DataHolderTest.java index 0e568400210..83b74779d12 100644 --- a/src/test/java/org/spongepowered/common/data/DataHolderTest.java +++ b/src/test/java/org/spongepowered/common/data/DataHolderTest.java @@ -1,9 +1,29 @@ -package data; +/* + * 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.data; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.animal.Cat; -import net.minecraft.world.level.Level; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -13,12 +33,12 @@ import org.spongepowered.api.block.BlockTypes; import org.spongepowered.api.block.entity.BlockEntity; import org.spongepowered.api.block.entity.BlockEntityArchetype; -import org.spongepowered.api.block.entity.BlockEntityType; import org.spongepowered.api.block.entity.BlockEntityTypes; -import org.spongepowered.api.data.*; +import org.spongepowered.api.data.DataRegistration; +import org.spongepowered.api.data.DataTransactionResult; +import org.spongepowered.api.data.Key; +import org.spongepowered.api.data.SerializableDataHolder; import org.spongepowered.api.data.persistence.DataContainer; -import org.spongepowered.api.data.persistence.DataQuery; -import org.spongepowered.api.data.persistence.DataSerializable; import org.spongepowered.api.data.value.Value; import org.spongepowered.api.entity.Entity; import org.spongepowered.api.entity.EntityTypes; @@ -28,8 +48,6 @@ import org.spongepowered.api.world.chunk.WorldChunk; import org.spongepowered.api.world.server.ServerWorld; import org.spongepowered.api.world.server.storage.ServerWorldProperties; -import org.spongepowered.common.data.SpongeDataManager; -import org.spongepowered.common.data.SpongeDataRegistration; import org.spongepowered.common.util.Constants; import org.spongepowered.math.vector.Vector3d; From dffb33cbe0a4f467a185caa6233647d00052e2ab Mon Sep 17 00:00:00 2001 From: aromaa Date: Mon, 29 Sep 2025 22:57:18 +0300 Subject: [PATCH 22/24] Fix entity custom Data API --- .../level/storage/TagValueInputAccessor.java | 37 +++++++++++++++++++ .../resources/mixins.sponge.accessors.json | 1 + .../mixin/core/world/entity/EntityMixin.java | 9 +---- 3 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 src/accessors/java/org/spongepowered/common/accessor/world/level/storage/TagValueInputAccessor.java diff --git a/src/accessors/java/org/spongepowered/common/accessor/world/level/storage/TagValueInputAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/world/level/storage/TagValueInputAccessor.java new file mode 100644 index 00000000000..012212391fe --- /dev/null +++ b/src/accessors/java/org/spongepowered/common/accessor/world/level/storage/TagValueInputAccessor.java @@ -0,0 +1,37 @@ +/* + * 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.accessor.world.level.storage; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.level.storage.TagValueInput; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(TagValueInput.class) +public interface TagValueInputAccessor { + + @Accessor("input") @Final CompoundTag accessor$input(); +} diff --git a/src/accessors/resources/mixins.sponge.accessors.json b/src/accessors/resources/mixins.sponge.accessors.json index d8234c3f63d..bf57fddb562 100644 --- a/src/accessors/resources/mixins.sponge.accessors.json +++ b/src/accessors/resources/mixins.sponge.accessors.json @@ -219,6 +219,7 @@ "world.level.saveddata.maps.MapItemSavedDataAccessor", "world.level.storage.PlayerDataStorageAccessor", "world.level.storage.PrimaryLevelDataAccessor", + "world.level.storage.TagValueInputAccessor", "world.phys.AABBAccessor", "world.scores.PlayerTeamAccessor", "world.scores.ScoreboardAccessor", 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 34d28462f2f..fe7a1bb8f1a 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 @@ -54,7 +54,6 @@ import net.minecraft.world.entity.PortalProcessor; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.component.CustomData; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; @@ -108,6 +107,7 @@ import org.spongepowered.common.accessor.server.level.ChunkMap_TrackedEntityAccessor; import org.spongepowered.common.accessor.world.entity.EntityAccessor; import org.spongepowered.common.accessor.world.entity.PortalProcessorAccessor; +import org.spongepowered.common.accessor.world.level.storage.TagValueInputAccessor; import org.spongepowered.common.bridge.commands.CommandSourceProviderBridge; import org.spongepowered.common.bridge.data.DataCompoundHolder; import org.spongepowered.common.bridge.data.SpongeDataHolderBridge; @@ -955,12 +955,7 @@ public void stopRiding() { @Inject(method = "load", at = @At("RETURN")) private void impl$ReadSpongeDataFromCompound(final ValueInput input, final CallbackInfo ci) { - // TODO If we are in Forge data is already present - final var spongeData = input.read(Constants.Sponge.Data.V3.SPONGE_TAG_KEY, CustomData.CODEC); - if (spongeData.isEmpty()) { - return; - } - this.data$setCompound(spongeData.get().copyTag()); // For vanilla we set the incoming nbt + this.data$setCompound(((TagValueInputAccessor) input).accessor$input()); // For vanilla we set the incoming nbt // Deserialize custom data... DataUtil.syncTagToData(this); this.data$setCompound(null); // done reading From dbc12077b46f6f408c084834adb64f7165c02409 Mon Sep 17 00:00:00 2001 From: aromaa Date: Mon, 29 Sep 2025 23:31:31 +0300 Subject: [PATCH 23/24] Bump test heap size to 4G --- forge/build.gradle.kts | 2 +- neoforge/build.gradle.kts | 2 +- vanilla/build.gradle.kts | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts index e93155b1415..18ec3c137b3 100644 --- a/forge/build.gradle.kts +++ b/forge/build.gradle.kts @@ -1,6 +1,5 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import net.minecraftforge.gradle.common.util.RunConfig -import org.gradle.api.tasks.JavaExec import org.gradle.internal.DefaultTaskExecutionRequest import org.spongepowered.gradle.impl.AWToAT import org.spongepowered.gradle.impl.IdeHelper @@ -429,6 +428,7 @@ tasks { test { useJUnitPlatform() + maxHeapSize = "4G" testClassesDirs = commonTest.get().output.classesDirs + testSources.get().output.classesDirs val runServer = minecraft.runs.getByName("server") diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts index 3dc2666d864..551f1993492 100644 --- a/neoforge/build.gradle.kts +++ b/neoforge/build.gradle.kts @@ -1,6 +1,5 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import net.neoforged.moddevgradle.internal.RunGameTask -import org.gradle.api.tasks.JavaExec import org.spongepowered.gradle.impl.AWToAT buildscript { @@ -405,6 +404,7 @@ tasks { test { useJUnitPlatform() + maxHeapSize = "4G" testClassesDirs = commonTest.get().output.classesDirs + testSources.get().output.classesDirs jvmArgs(runServer.get().jvmArgs) diff --git a/vanilla/build.gradle.kts b/vanilla/build.gradle.kts index f655f9f873e..271a41a0c0e 100644 --- a/vanilla/build.gradle.kts +++ b/vanilla/build.gradle.kts @@ -510,6 +510,7 @@ tasks { test { useJUnitPlatform() + maxHeapSize = "4G" testClassesDirs = commonTest.get().output.classesDirs + testSources.get().output.classesDirs val runServer = minecraft.runs.server().get() From 898bd33ca3274fb015627d811806b73c91da5e5e Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Tue, 30 Sep 2025 19:51:40 -0700 Subject: [PATCH 24/24] feat(minecraft): update to 1.21.9 Signed-off-by: Gabriel Harris-Rouquette --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 0203cf330be..d8b9710cb8e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ mixinConfigs=mixins.sponge.accessors.json,mixins.sponge.api.json,mixins.sponge.c mixins.sponge.tracker.json,mixins.sponge.ipforward.json,mixins.sponge.optimization.json,mixins.sponge.test.json superClassChanges=common.superclasschange -minecraftVersion=1.21.9-rc1 +minecraftVersion=1.21.9 recommendedVersion=0-SNAPSHOT org.gradle.dependency.verification.console=verbose