diff --git a/SpongeAPI b/SpongeAPI index 0a42e85e8c0..1e5c9168abf 160000 --- a/SpongeAPI +++ b/SpongeAPI @@ -1 +1 @@ -Subproject commit 0a42e85e8c05399bdc72dcae97678e78ad46caff +Subproject commit 1e5c9168abfeb4297aa67e4fb84397948aaa5939 diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts index 92953a23b93..25e1e11f3fd 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 @@ -432,6 +431,7 @@ tasks { test { useJUnitPlatform() + maxHeapSize = "4G" testClassesDirs = commonTest.get().output.classesDirs + testSources.get().output.classesDirs val runServer = minecraft.runs.getByName("server") 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..2e07feb0af8 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("SideChain")); + 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..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 @@ -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", + "CopperOxidations", + WeatheringCopper.WeatherState.class, + "getSerializedName", + "sponge" ) ); } diff --git a/gradle.properties b/gradle.properties index 0730aa56ae4..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.8 +minecraftVersion=1.21.9 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 ba9bbd37753..df1a7205e1f 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -1517,6 +1517,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -1594,6 +1618,23 @@ + + + + + + + + + + + + + + + + + @@ -2377,6 +2418,14 @@ + + + + + + + + @@ -2480,6 +2529,14 @@ + + + + + + + + @@ -3859,6 +3916,11 @@ + + + + + @@ -3867,6 +3929,14 @@ + + + + + + + + diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts index 13097d491c3..5373799f983 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/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..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 @@ -25,10 +25,10 @@ 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; -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; @@ -40,23 +40,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/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/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/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/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/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/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/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/accessors/java/org/spongepowered/common/accessor/advancements/critereon/MinMaxBounds_DoublesAccessor.java b/src/accessors/java/org/spongepowered/common/accessor/world/level/storage/TagValueInputAccessor.java similarity index 71% rename from src/accessors/java/org/spongepowered/common/accessor/advancements/critereon/MinMaxBounds_DoublesAccessor.java rename to src/accessors/java/org/spongepowered/common/accessor/world/level/storage/TagValueInputAccessor.java index 09e8543900a..012212391fe 100644 --- a/src/accessors/java/org/spongepowered/common/accessor/advancements/critereon/MinMaxBounds_DoublesAccessor.java +++ b/src/accessors/java/org/spongepowered/common/accessor/world/level/storage/TagValueInputAccessor.java @@ -22,20 +22,16 @@ * 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.accessor.world.level.storage; -import net.minecraft.advancements.critereon.MinMaxBounds; +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.Invoker; -import org.spongepowered.common.UntransformedInvokerError; +import org.spongepowered.asm.mixin.gen.Accessor; -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(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..e3bfa53181a 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", @@ -62,6 +60,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", @@ -219,6 +218,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/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/adventure/SpongeAdventure.java b/src/main/java/org/spongepowered/common/adventure/SpongeAdventure.java index ddf21e6cb2d..f6c7eaa7641 100644 --- a/src/main/java/org/spongepowered/common/adventure/SpongeAdventure.java +++ b/src/main/java/org/spongepowered/common/adventure/SpongeAdventure.java @@ -72,17 +72,18 @@ 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; -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; @@ -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/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/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/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 } 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/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/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/block/state/BlockStateDataProvider.java b/src/main/java/org/spongepowered/common/data/provider/block/state/BlockStateDataProvider.java index 924648252de..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 @@ -62,13 +62,8 @@ 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); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CRAFTING, BlockStateProperties.CRAFTING); BlockStateDataProvider.registerProperty(registrator, BlockStateKeys.CREAKING_HEART_STATE, BlockStateProperties.CREAKING_HEART_STATE); @@ -139,8 +134,15 @@ 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.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/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/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/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/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/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/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/ServerPlayerData.java b/src/main/java/org/spongepowered/common/data/provider/entity/ServerPlayerData.java index 5263916c19f..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 @@ -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) @@ -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/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/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/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/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/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/data/provider/item/stack/SpawnEggItemStackData.java b/src/main/java/org/spongepowered/common/data/provider/item/stack/SpawnEggItemStackData.java index 81f7b503cb3..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 @@ -25,14 +25,15 @@ 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; import org.spongepowered.common.data.provider.DataProviderRegistrator; import org.spongepowered.common.entity.SpongeEntityArchetypeBuilder; @@ -47,11 +48,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 +65,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/data/provider/world/WorldPropertiesData.java b/src/main/java/org/spongepowered/common/data/provider/world/WorldPropertiesData.java index 73b96f28960..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()) @@ -74,7 +79,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/effect/util/ViewerPacketUtil.java b/src/main/java/org/spongepowered/common/effect/util/ViewerPacketUtil.java index 3912604c142..63451301242 100644 --- a/src/main/java/org/spongepowered/common/effect/util/ViewerPacketUtil.java +++ b/src/main/java/org/spongepowered/common/effect/util/ViewerPacketUtil.java @@ -143,7 +143,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..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 @@ -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; @@ -46,6 +45,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; @@ -82,9 +82,11 @@ 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; +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; @@ -99,6 +101,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; @@ -115,16 +118,16 @@ 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; 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); + this.entityData.set(AvatarAccessor.accessor$DATA_PLAYER_MODE_CUSTOMISATION(), Constants.Sponge.Entity.Human.PLAYER_MODEL_FLAG_ALL); } @Override @@ -138,13 +141,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 @@ -195,7 +200,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()); }); } @@ -306,26 +311,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) { - 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.services().nameToIdCache().get(minecraftAccount).flatMap(name -> + server.services().profileResolver().fetchByName(name.name()) + ).orElseGet(() -> { + final @Nullable ProfileResult result = server.services().sessionService().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.services().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.partialProfile().properties().replaceValues(ProfileProperty.TEXTURES, profile.properties().get(ProfileProperty.TEXTURES)); if (this.isAliveAndInWorld()) { this.respawnOnClient(); } @@ -335,22 +341,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.services().nameToIdCache().get(minecraftAccount).flatMap(name -> + server.services().profileResolver().fetchByName(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.partialProfile().properties().clear(); + this.fakeProfile.partialProfile().properties().putAll(profile.properties()); if (this.isAliveAndInWorld()) { this.respawnOnClient(); } @@ -373,7 +373,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; } @@ -381,7 +381,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())); @@ -399,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 ))); } @@ -411,7 +410,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); } /** @@ -437,7 +436,7 @@ public ClientboundPlayerInfoUpdatePacket createPlayerListPacket(final EnumSet... packets) { + public void pushPackets(final Packet... packets) { this.pushPackets(null, packets); // null = all players } @@ -457,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 { @@ -473,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/entity/player/SpongeUserData.java b/src/main/java/org/spongepowered/common/entity/player/SpongeUserData.java index 67a1857b79c..21f11f430cd 100644 --- a/src/main/java/org/spongepowered/common/entity/player/SpongeUserData.java +++ b/src/main/java/org/spongepowered/common/entity/player/SpongeUserData.java @@ -149,7 +149,7 @@ public static SpongeUserData create(final GameProfile profile) throws IOExceptio } final LevelStorageSource.LevelStorageAccess storageSource = ((MinecraftServerAccessor) Sponge.server()).accessor$storageSource(); - final Path p = storageSource.getLevelPath(LevelResource.PLAYER_DATA_DIR).resolve(profile.getId().toString() + ".dat"); + final Path p = storageSource.getLevelPath(LevelResource.PLAYER_DATA_DIR).resolve(profile.id().toString() + ".dat"); if (!Files.exists(p)) { return new SpongeUserData(profile, new CompoundTag()); } @@ -270,12 +270,12 @@ public void writeCompound(final CompoundTag compound) { @Override public UUID uniqueId() { - return this.profile.getId(); + return this.profile.id(); } @Override public String name() { - return this.profile.getName(); + return this.profile.name(); } @Override @@ -288,8 +288,8 @@ public DataContainer toContainer() { // TODO More data return DataContainer.createNew() .set(Queries.CONTENT_VERSION, this.contentVersion()) - .set(Constants.Entity.Player.UUID, this.profile.getId()) - .set(Constants.Entity.Player.NAME, this.profile.getName()) + .set(Constants.Entity.Player.UUID, this.profile.id()) + .set(Constants.Entity.Player.NAME, this.profile.name()) .set(Constants.Entity.Player.SPAWNS, this.spawnLocations); } @@ -473,7 +473,7 @@ public boolean isOnline() { @Override public Optional 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/event/SpongeCommonEventFactory.java b/src/main/java/org/spongepowered/common/event/SpongeCommonEventFactory.java index 46b5115ace2..0c93973febf 100644 --- a/src/main/java/org/spongepowered/common/event/SpongeCommonEventFactory.java +++ b/src/main/java/org/spongepowered/common/event/SpongeCommonEventFactory.java @@ -530,10 +530,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; } @@ -541,30 +537,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/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/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/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/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/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/item/SpongeItemStack.java b/src/main/java/org/spongepowered/common/item/SpongeItemStack.java index ced0b591832..fd2224756c1 100644 --- a/src/main/java/org/spongepowered/common/item/SpongeItemStack.java +++ b/src/main/java/org/spongepowered/common/item/SpongeItemStack.java @@ -43,7 +43,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 +78,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 +197,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 +284,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 +314,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 +351,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/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/network/packet/SpongePacketHandler.java b/src/main/java/org/spongepowered/common/network/packet/SpongePacketHandler.java index ed0bf11cd26..98aa8a2a3c9 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().services().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().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 1671fe3d08c..49264d46148 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,21 +55,36 @@ 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(); - 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); } + 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(); + final UUID uniqueId = mcProfile.id(); + final String name = mcProfile.name().isEmpty() ? null : mcProfile.name(); 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(); } @@ -134,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 f9ea16c603b..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).getProfileCache(); + 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/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/registry/loader/VanillaRegistryLoader.java b/src/main/java/org/spongepowered/common/registry/loader/VanillaRegistryLoader.java index d10ae11d2f1..49362da4428 100644 --- a/src/main/java/org/spongepowered/common/registry/loader/VanillaRegistryLoader.java +++ b/src/main/java/org/spongepowered/common/registry/loader/VanillaRegistryLoader.java @@ -153,7 +153,7 @@ private void loadInstanceRegistries() { final var materials = new HashMap(); final var knownMaterials = new ArmorMaterial[]{ ArmorMaterials.LEATHER,ArmorMaterials.CHAINMAIL, ArmorMaterials.IRON, ArmorMaterials.GOLD, ArmorMaterials.DIAMOND, - ArmorMaterials.TURTLE_SCUTE,ArmorMaterials.NETHERITE, ArmorMaterials.ARMADILLO_SCUTE, + ArmorMaterials.TURTLE_SCUTE,ArmorMaterials.NETHERITE, ArmorMaterials.ARMADILLO_SCUTE, ArmorMaterials.COPPER, }; for (final ArmorMaterial armorMaterial : knownMaterials) { materials.put(armorMaterial, armorMaterial.assetId().location().toString()); @@ -276,6 +276,7 @@ private static RegistryLoader itemTier() { l.add(ItemTiers.NETHERITE, k -> (ItemTier) (Object) ToolMaterial.NETHERITE); l.add(ItemTiers.STONE, k -> (ItemTier) (Object) ToolMaterial.STONE); l.add(ItemTiers.WOOD, k -> (ItemTier) (Object) ToolMaterial.WOOD); + l.add(ItemTiers.COPPER, k -> (ItemTier) (Object) ToolMaterial.COPPER); }); } 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/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/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 85e8b0d61f8..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,8 @@ 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; import org.spongepowered.api.Sponge; @@ -47,23 +49,23 @@ public class SpongeUserBanList extends UserBanList { public SpongeUserBanList(final File file) { - super(file); + super(file, new EmptyNotificationService()); } @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), @@ -83,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 @@ -94,9 +97,10 @@ public boolean isEmpty() { } @Override - public void remove(final com.mojang.authlib.GameProfile 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 4960633e903..b31e2b0a85e 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 @@ -102,7 +102,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/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..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 @@ -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); } } }; @@ -78,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); } @@ -93,17 +96,17 @@ public Optional associatedObject() { return Optional.empty(); } - return Sponge.server().player(this.player.getId()); + return Sponge.server().player(this.player.id()); } 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().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 7b450b45d77..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,8 @@ */ 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; import org.spongepowered.api.Sponge; @@ -42,11 +44,11 @@ public class SpongeUserWhiteList extends UserWhiteList { public SpongeUserWhiteList(final File file) { - super(file); + super(file, new EmptyNotificationService()); } @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(); } @@ -61,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 com.mojang.authlib.GameProfile 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/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..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,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.services().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); @@ -134,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()); } @@ -233,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)) { @@ -246,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/java/org/spongepowered/common/util/Constants.java b/src/main/java/org/spongepowered/common/util/Constants.java index 5349e93abb8..fc0c2e5c025 100644 --- a/src/main/java/org/spongepowered/common/util/Constants.java +++ b/src/main/java/org/spongepowered/common/util/Constants.java @@ -1547,6 +1547,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/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/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/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..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; @@ -39,16 +40,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; @@ -63,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; @@ -87,7 +87,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 +133,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 +145,7 @@ public SpongeWorldManager(final MinecraftServer server) { throw new RuntimeException(e); } this.worlds = ((MinecraftServerAccessor) this.server).accessor$levels(); + this.levelLoadListener = LoggingLevelLoadListener.forDedicatedServer(); } @Override @@ -693,12 +694,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,14 +901,13 @@ 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. - world.getWorldBorder().applySettings(levelData.getWorldBorder()); + levelData.getLegacyWorldBorderSettings().ifPresent(world.getWorldBorder()::applySettings); PlatformHooks.INSTANCE.getWorldHooks().postLoadWorld(world); return world; } @@ -939,12 +933,12 @@ 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); + 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); } @@ -983,20 +977,16 @@ 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 int spawnRadius = SpongeWorldManager.getSpawnRadius((ServerLevelData) level.getLevelData()); - final int spawnSize = spawnRadius > 0 ? Mth.square(ChunkProgressListener.calculateDiameter(spawnRadius)) : 0; + final var respawnData = level.getRespawnData(); + level.setRespawnData(new LevelData.RespawnData(respawnData.globalPos(), respawnData.pitch(), respawnData.yaw())); 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() ); @@ -1012,21 +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 ChunkPos chunkPos = new ChunkPos(spawnPoint); - final ChunkProgressListener progressListener = ((ServerLevelBridge) level).bridge$getChunkProgressListener(); - progressListener.updateSpawnPos(chunkPos); + final var respawnData = level.getRespawnData(); 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(); - } + level.setRespawnData(respawnData); ((MinecraftServerAccessor) this.server).accessor$nextTickTimeNanos(Util.getNanos() + 10L * TimeUtil.NANOSECONDS_PER_MILLISECOND); ((MinecraftServerAccessor) this.server).accessor$waitUntilNextTick(); @@ -1035,11 +1014,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/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/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/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/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/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/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/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/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/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/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..0bd8ef3729c 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); @@ -318,7 +320,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/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/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/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/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/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/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..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,9 +24,9 @@ */ 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; import net.minecraft.server.players.PlayerList; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -42,21 +42,22 @@ 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 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); } @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/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/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 1b152e210e2..a854ee810ec 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,11 +41,9 @@ import net.minecraft.server.Services; import net.minecraft.server.WorldStem; import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.progress.ChunkProgressListener; -import net.minecraft.server.level.progress.ChunkProgressListenerFactory; +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.players.GameProfileCache; import net.minecraft.server.players.PlayerList; import net.minecraft.util.thread.BlockableEventLoop; import net.minecraft.world.Difficulty; @@ -54,7 +52,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; @@ -113,11 +110,9 @@ import java.io.IOException; import java.net.Proxy; -import java.util.Collection; import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.concurrent.CompletableFuture; @Mixin(MinecraftServer.class) public abstract class MinecraftServerMixin implements SpongeServer, MinecraftServerBridge, CommandSourceProviderBridge, SubjectProxy, @@ -129,20 +124,17 @@ 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 GameProfileCache shadow$getProfileCache(); - @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(); @Shadow @Nullable public abstract ServerLevel shadow$getLevel(ResourceKey $$0); // @formatter:on @@ -202,7 +194,7 @@ public Subject subject() { private void impl$setThreadOnServerPhaseTracker( Thread thread, LevelStorageSource.LevelStorageAccess storageAccess, PackRepository packRepo, WorldStem stem, Proxy proxy, DataFixer fixer, - Services services, ChunkProgressListenerFactory progress, CallbackInfo ci + Services services, LevelLoadListener progress, CallbackInfo ci ) { try { PhaseTracker.getServerInstanceExplicitly().setThread(thread); @@ -235,8 +227,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); @@ -256,10 +252,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); } } @@ -268,7 +266,7 @@ public Subject subject() { * @reason Multi world. */ @Overwrite - private void prepareLevels(final ChunkProgressListener progressListener) { + private void prepareLevels() { this.worldManager().prepareLevels(); } @@ -284,7 +282,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); } @@ -433,7 +431,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$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/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/dedicated/DedicatedPlayerListMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/dedicated/DedicatedPlayerListMixin.java index 6a23e98a14a..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 @@ -24,11 +24,12 @@ */ 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; 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; import org.spongepowered.api.Sponge; @@ -46,18 +47,18 @@ 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) - 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/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 4920948720d..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 @@ -44,18 +44,18 @@ 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; 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; +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; -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; @@ -63,6 +63,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; @@ -159,16 +160,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 +187,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 +209,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()) { @@ -283,7 +278,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); } @@ -300,7 +295,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 @@ -355,18 +350,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); @@ -387,7 +370,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); @@ -477,7 +461,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) @@ -526,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/core/server/level/ServerPlayerMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/level/ServerPlayerMixin.java index 6e754a253ee..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 @@ -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 @@ -981,13 +1009,13 @@ 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) { 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()); - playerRespawnDestination = player.getServer().overworld(); + + "the player will be moved to the spawn of the default world.", player.getGameProfile().name()); + playerRespawnDestination = ((ServerPlayerAccessor) player).accessor$server().overworld(); } final RespawnPlayerEvent.SelectWorld event = SpongeEventFactory.createRespawnPlayerEventSelectWorld(PhaseTracker.getInstance().currentCause(), @@ -1014,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/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 a798a21ca54..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 @@ -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; @@ -81,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; @@ -94,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 @@ -121,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 { @@ -130,15 +131,15 @@ 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; }); } @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 2de1e77ef32..964eb82b63e 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; @@ -137,8 +138,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; } @@ -172,7 +173,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 @@ -191,7 +192,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; }); @@ -254,10 +255,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/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/GameProfileCacheMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/GameProfileCacheMixin.java index 33cd58fd114..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 @@ -25,7 +25,8 @@ package org.spongepowered.common.mixin.core.server.players; import com.mojang.authlib.GameProfileRepository; -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.api.profile.GameProfileManager; @@ -48,11 +49,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 @@ -68,7 +69,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(); } @@ -84,7 +85,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(); } @@ -94,18 +95,19 @@ 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(); + 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.getId(), profile.getId()) && - Objects.equals(current.getName(), profile.getName()) && !full) { + if (current != null && Objects.equals(current.id(), profile.id()) && + Objects.equals(current.name(), profile.name()) && !full) { return; } - this.shadow$add(profile); - accessor = this.profilesByUUID.get(profile.getId()); - if (accessor == null || accessor.invoker$getProfile() != profile) { + final var nameAndIDToAdd = new NameAndId(profile); + this.shadow$add(nameAndIDToAdd); + accessor = this.profilesByUUID.get(profile.id()); + if (accessor == null || accessor.invoker$nameAndId() != nameAndIDToAdd) { return; } final GameProfileCache_GameProfileInfoBridge bridge = (GameProfileCache_GameProfileInfoBridge) accessor; @@ -116,18 +118,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); @@ -139,17 +141,18 @@ 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()); } } @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(); } 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/server/players/PlayerListMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/server/players/PlayerListMixin.java index d33c81144a5..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 @@ -28,6 +28,7 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; import com.llamalad7.mixinextras.sugar.Local; import com.llamalad7.mixinextras.sugar.Share; import com.llamalad7.mixinextras.sugar.ref.LocalRef; @@ -53,16 +54,15 @@ 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.ValueInput; import org.checkerframework.checker.nullness.qual.Nullable; import org.objectweb.asm.Opcodes; import org.slf4j.Logger; @@ -156,13 +156,11 @@ 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 @Final private Map playersByUUID; - @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 public abstract int shadow$getMaxPlayers(); @Shadow protected abstract void shadow$save(net.minecraft.server.level.ServerPlayer $$0); // @formatter:on @@ -182,10 +180,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 -> { @@ -226,7 +224,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,38 +246,23 @@ 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; }, 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; @@ -289,13 +272,13 @@ 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(); - final BlockPos spawnPoint = mcWorld.getSharedSpawnPos(); + + "the player will be moved to the spawn of the default world.", mcPlayer.getGameProfile().name()); + mcWorld = this.server.overworld(); + final BlockPos spawnPoint = mcWorld.getRespawnData().pos(); mcPlayer.setPos(spawnPoint.getX() + 0.5, spawnPoint.getY() + 0.5, spawnPoint.getZ() + 0.5); } @@ -312,7 +295,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); } @@ -324,15 +307,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 ) ) @@ -349,9 +334,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", @@ -385,26 +370,26 @@ 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); } - @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()); } @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( @@ -415,7 +400,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); @@ -448,7 +433,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())); @@ -488,29 +473,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; } @@ -519,11 +488,11 @@ 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, - 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; @@ -533,9 +502,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; @@ -562,27 +531,21 @@ 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) { - 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); 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) { @@ -596,9 +559,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; } @@ -607,7 +570,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; @@ -643,7 +606,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { } 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())); if (event.target().isPresent()) { boundChatType = boundChatType.withTargetName(SpongeAdventure.asVanilla(event.target().get())); 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/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/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..abe8beee105 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; @@ -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; } @@ -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 @@ -1000,7 +995,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/decoration/MannequinMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/decoration/MannequinMixin.java new file mode 100644 index 00000000000..10b5feed971 --- /dev/null +++ b/src/mixins/java/org/spongepowered/common/mixin/core/world/entity/decoration/MannequinMixin.java @@ -0,0 +1,34 @@ +/* + * 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.world.entity.decoration; + +import org.spongepowered.api.entity.Mannequin; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.common.mixin.core.world.entity.AvatarMixin; + +@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/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/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/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/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/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/LevelMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/LevelMixin.java index 48764abb719..56621141ff3 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 @@ -165,7 +163,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 -> { 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/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/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..3d3b97ff592 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 @@ -31,7 +31,6 @@ import org.spongepowered.api.data.type.DyeColor; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.common.bridge.CustomNameableBridge; @@ -44,13 +43,13 @@ @Mixin(BannerBlockEntity.class) public abstract class BannerBlockEntityMixin extends BlockEntityMixin implements BannerBlockEntityBridge, CustomNameableBridge { - @Shadow @Final @Mutable private net.minecraft.world.item.DyeColor baseColor; + @Shadow @Final @org.spongepowered.asm.mixin.Mutable private net.minecraft.world.item.DyeColor baseColor; @Shadow @Nullable private Component name; @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/block/entity/BlockEntityMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/block/entity/BlockEntityMixin.java index 9a8039c4793..c037f9198ad 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 @@ -29,7 +29,6 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.component.CustomData; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.storage.TagValueOutput; @@ -37,6 +36,8 @@ import net.minecraft.world.level.storage.ValueOutput; 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; @@ -47,14 +48,17 @@ 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 org.spongepowered.common.util.Constants; +import java.util.Arrays; +import java.util.List; import java.util.StringJoiner; -@Mixin(BlockEntity.class) -public abstract class BlockEntityMixin implements BlockEntityBridge, DataCompoundHolder { +@Mixin(net.minecraft.world.level.block.entity.BlockEntity.class) +public abstract class BlockEntityMixin implements BlockEntityBridge, DataCompoundHolder, SpongeMutableDataHolder { //@formatter:off @Shadow @Final private BlockEntityType type; @@ -134,4 +138,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()); + } } 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/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/world/level/storage/PlayerDataStorageMixin.java b/src/mixins/java/org/spongepowered/common/mixin/core/world/level/storage/PlayerDataStorageMixin.java index a44d4984345..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 @@ -26,25 +26,17 @@ 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; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.common.SpongeCommon; 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 { @@ -53,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/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/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/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); 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/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; + } } diff --git a/src/mixins/java/org/spongepowered/common/mixin/ipforward/server/dedicated/DedicatedServerMixin_IpForward.java b/src/mixins/java/org/spongepowered/common/mixin/ipforward/server/dedicated/DedicatedServerMixin_IpForward.java index 6c39c5ff3b4..0daac1911ad 100644 --- a/src/mixins/java/org/spongepowered/common/mixin/ipforward/server/dedicated/DedicatedServerMixin_IpForward.java +++ b/src/mixins/java/org/spongepowered/common/mixin/ipforward/server/dedicated/DedicatedServerMixin_IpForward.java @@ -40,10 +40,12 @@ @Mixin(DedicatedServer.class) public class DedicatedServerMixin_IpForward { - @Shadow @Final private static Logger LOGGER; + @Shadow + @Final + static Logger LOGGER; @Inject(method = "initServer", at = @At(value = "INVOKE_STRING", remap = false, target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;)V", - args = "ldc=**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!")) + args = "ldc=**** SERVER IS RUNNING IN OFFLINE/INSECURE MODE!")) private void ipForward$logEnabled(final CallbackInfoReturnable ci) { final IpForwardingCategory.Mode mode = SpongeConfigs.getCommon().get().ipForwarding.mode; if (mode != IpForwardingCategory.Mode.NONE) { @@ -52,10 +54,10 @@ public class DedicatedServerMixin_IpForward { } } - @WrapOperation(method = "initServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/GameProfileCache;setUsesAuthentication(Z)V")) - private void ipForwarding$proxyOnlineMode(final boolean value, final Operation original) { + @WrapOperation(method = "initServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/dedicated/DedicatedServer;setUsesAuthentication(Z)V")) + private void ipForwarding$proxyOnlineMode(final DedicatedServer instance, final boolean value, final Operation original) { final IpForwardingCategory ipForwarding = SpongeConfigs.getCommon().get().ipForwarding; - original.call(ipForwarding.mode != IpForwardingCategory.Mode.NONE + original.call(instance, ipForwarding.mode != IpForwardingCategory.Mode.NONE ? ipForwarding.onlineMode : value); } 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/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/dedicated/DedicatedServerMixin_Tracker.java b/src/mixins/java/org/spongepowered/common/mixin/tracker/server/dedicated/DedicatedServerMixin_Tracker.java index bc9d975b68a..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 @@ -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 @@ -70,8 +70,8 @@ public boolean isUnderSpawnProtection(final ServerLevel worldIn, final BlockPos } } - final BlockPos spawnPoint = worldIn.getSharedSpawnPos(); - final int protectionRadius = this.shadow$getSpawnProtectionRadius(); + final BlockPos spawnPoint = worldIn.getRespawnData().pos(); + 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/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/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; } 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/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 30775de2b71..15355cba0b5 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", @@ -387,6 +389,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/src/mixins/resources/mixins.sponge.core.json b/src/mixins/resources/mixins.sponge.core.json index 07ef9e6c57c..518e6d95987 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", @@ -94,6 +93,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", @@ -118,6 +118,7 @@ "world.damagesource.DamageSourcesMixin", "world.entity.ActiveChunkReferentMixin", "world.entity.AgableMobMixin", + "world.entity.AvatarMixin", "world.entity.EntityMaxAirMixin", "world.entity.EntityMixin", "world.entity.EntitySelectorMixin", @@ -128,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/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..83b74779d12 --- /dev/null +++ b/src/test/java/org/spongepowered/common/data/DataHolderTest.java @@ -0,0 +1,103 @@ +/* + * 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 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.BlockEntityTypes; +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.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.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); + } +} 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()); + } + +} diff --git a/vanilla/build.gradle.kts b/vanilla/build.gradle.kts index f38bf025597..0de671757e9 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() 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..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) { + 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); + 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 7fa79ba1be8..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) { - if (super.mouseClicked(mouseX, mouseY, button)) { + 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 7ebcc9ef51e..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,13 +33,13 @@ 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; import java.util.Arrays; import java.util.List; -import java.util.Objects; import java.util.function.Consumer; import java.util.function.Supplier; @@ -67,7 +67,7 @@ public Screen getScreen() { } public int getBottom() { - return this.getY() + this.headerHeight; + return this.getY() + this.getHeight(); } public E getCurrentHoveredEntry() { @@ -107,10 +107,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() { @@ -131,22 +131,29 @@ public void setSelected(@Nullable final E entry) { super.setSelected(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 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(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(event, 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) { + 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; } @@ -171,27 +178,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 +234,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 8790eb4acd5..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; @@ -50,23 +51,28 @@ 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_) { + public boolean mouseClicked(final MouseButtonEvent event, 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/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); } } 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(); }