diff --git a/src/main/java/org/spongepowered/common/bridge/data/TransientBridge.java b/src/main/java/org/spongepowered/common/bridge/data/TransientBridge.java new file mode 100644 index 00000000000..e8c8d63b203 --- /dev/null +++ b/src/main/java/org/spongepowered/common/bridge/data/TransientBridge.java @@ -0,0 +1,32 @@ +/* + * 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.bridge.data; + +public interface TransientBridge { + + boolean bridge$isTransient(); + + void bridge$setTransient(boolean value); +} diff --git a/src/main/java/org/spongepowered/common/bridge/world/entity/EntityBridge.java b/src/main/java/org/spongepowered/common/bridge/world/entity/EntityBridge.java index c02aee00d48..98481634d76 100644 --- a/src/main/java/org/spongepowered/common/bridge/world/entity/EntityBridge.java +++ b/src/main/java/org/spongepowered/common/bridge/world/entity/EntityBridge.java @@ -69,8 +69,6 @@ public interface EntityBridge { default void bridge$onCancelledBlockChange(final EntityTickContext phaseContext) { } - void bridge$setTransient(boolean value); - boolean bridge$dismountRidingEntity(DismountType type); Entity bridge$changeDimension(ServerLevel targetWorld, PortalLogic teleporter); 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 e8bf0dbe4c6..385a55b994a 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,9 +197,6 @@ public static void register(final DataProviderRegistrator registrator) { h.getTags().clear(); h.getTags().addAll(v); }) - .create(Keys.TRANSIENT) - .get(h -> ((EntityAccessor) h).invoker$getEncodeId() == null) - .set((h, v) -> ((EntityBridge) h).bridge$setTransient(v)) .create(Keys.VEHICLE) .get(h -> (org.spongepowered.api.entity.Entity) h.getVehicle()) .set((h, v) -> h.startRiding((Entity) v, true)) 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 a0a353b1a30..a6044d3c076 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 @@ -110,6 +110,7 @@ public void registerProviders() { ThrowableItemProjectileData.register(this.registrator); TNTData.register(this.registrator); TraderLlamaData.register(this.registrator); + TransientData.register(this.registrator); TropicalFishData.register(this.registrator); TurtleData.register(this.registrator); VanishableData.register(this.registrator); diff --git a/src/main/java/org/spongepowered/common/data/provider/entity/TransientData.java b/src/main/java/org/spongepowered/common/data/provider/entity/TransientData.java new file mode 100644 index 00000000000..e5061b58ac6 --- /dev/null +++ b/src/main/java/org/spongepowered/common/data/provider/entity/TransientData.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 org.spongepowered.api.data.Keys; +import org.spongepowered.common.bridge.data.TransientBridge; +import org.spongepowered.common.data.provider.DataProviderRegistrator; + +public final class TransientData { + + private TransientData() { + } + + // @formatter:off + public static void register(final DataProviderRegistrator registrator) { + registrator + .asMutable(TransientBridge.class) + .create(Keys.TRANSIENT) + .get(TransientBridge::bridge$isTransient) + .set(TransientBridge::bridge$setTransient); + } + // @formatter:on +} 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 bf8d11d3078..f252f5553c0 100644 --- a/src/main/java/org/spongepowered/common/entity/player/SpongeUserData.java +++ b/src/main/java/org/spongepowered/common/entity/player/SpongeUserData.java @@ -70,6 +70,7 @@ import org.spongepowered.common.bridge.authlib.GameProfileHolderBridge; import org.spongepowered.common.bridge.data.DataCompoundHolder; import org.spongepowered.common.bridge.data.SpongeDataHolderBridge; +import org.spongepowered.common.bridge.data.TransientBridge; import org.spongepowered.common.bridge.data.VanishableBridge; import org.spongepowered.common.bridge.permissions.SubjectBridge; import org.spongepowered.common.bridge.world.entity.player.BedLocationHolderBridge; @@ -107,7 +108,7 @@ * There should be no difference between the two. */ public final class SpongeUserData implements Identifiable, DataSerializable, BedLocationHolderBridge, SpongeMutableDataHolder, - DataCompoundHolder, VanishableBridge, GameProfileHolderBridge, User, BridgeSubject { + DataCompoundHolder, VanishableBridge, GameProfileHolderBridge, User, BridgeSubject, TransientBridge { private final Map spawnLocations = Maps.newHashMap(); @@ -124,6 +125,7 @@ public final class SpongeUserData implements Identifiable, DataSerializable, Bed private boolean vanishIgnoresCollision; private boolean vanishPreventsTargeting; private final GameProfile profile; + private boolean isTransient; private @Nullable SpongeUserInventory inventory; // lazy load when accessing inventory private @Nullable PlayerEnderChestContainer enderChest; // lazy load when accessing inventory @@ -623,4 +625,13 @@ public String identifier() { return this.uniqueId().toString(); } + @Override + public boolean bridge$isTransient() { + return this.isTransient; + } + + @Override + public void bridge$setTransient(final boolean value) { + this.isTransient = value; + } } 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 b86b3cd6a24..90449dbb77c 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 @@ -906,4 +906,9 @@ public void sendMessage(final OutgoingChatMessage $$0, final boolean $$1, final public void bridge$replaceWorldBorder(final @Nullable WorldBorder border) { this.impl$worldBorder = border; } + + @Override + public boolean bridge$isTransient() { + return this.impl$transient; + } } 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 fc5bfdb1d7f..28c3370e073 100644 --- 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 @@ -94,6 +94,7 @@ import org.spongepowered.common.SpongeServer; import org.spongepowered.common.adventure.SpongeAdventure; import org.spongepowered.common.bridge.client.server.IntegratedPlayerListBridge; +import org.spongepowered.common.bridge.data.TransientBridge; import org.spongepowered.common.bridge.data.VanishableBridge; import org.spongepowered.common.bridge.network.ConnectionBridge; import org.spongepowered.common.bridge.server.ServerScoreboardBridge; @@ -673,4 +674,10 @@ public abstract class PlayerListMixin implements PlayerListBridge { this.shadow$broadcastChatMessage($$0, filter, $$2, boundChatType); } + @Inject(method = "save", at = @At("HEAD"), cancellable = true) + private void impl$onSave(final net.minecraft.server.level.ServerPlayer player, final CallbackInfo ci) { + if (((TransientBridge) player).bridge$isTransient()) { + ci.cancel(); + } + } } 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 23314c62f36..0d9624f924b 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 @@ -104,6 +104,7 @@ import org.spongepowered.common.bridge.commands.CommandSourceProviderBridge; import org.spongepowered.common.bridge.data.DataCompoundHolder; import org.spongepowered.common.bridge.data.SpongeDataHolderBridge; +import org.spongepowered.common.bridge.data.TransientBridge; import org.spongepowered.common.bridge.data.VanishableBridge; import org.spongepowered.common.bridge.world.entity.EntityBridge; import org.spongepowered.common.bridge.world.entity.PlatformEntityBridge; @@ -137,7 +138,7 @@ import java.util.UUID; @Mixin(Entity.class) -public abstract class EntityMixin implements EntityBridge, PlatformEntityBridge, VanishableBridge, CommandSourceProviderBridge, DataCompoundHolder { +public abstract class EntityMixin implements EntityBridge, PlatformEntityBridge, VanishableBridge, CommandSourceProviderBridge, DataCompoundHolder, TransientBridge { // @formatter:off @@ -231,12 +232,12 @@ public abstract class EntityMixin implements EntityBridge, PlatformEntityBridge, @Shadow public abstract int shadow$getPortalCooldown(); @Shadow public abstract boolean shadow$onGround(); - + @Shadow @Nullable protected abstract String shadow$getEncodeId(); // @formatter:on private boolean impl$isConstructing = true; private VanishState impl$vanishState = VanishState.unvanished(); - private boolean impl$transient = false; + protected boolean impl$transient = false; private boolean impl$shouldFireRepositionEvent = true; private WeakReference impl$originalDestinationWorld = null; private boolean impl$customPortal = false; @@ -441,6 +442,11 @@ public abstract class EntityMixin implements EntityBridge, PlatformEntityBridge, } } + @Override + public boolean bridge$isTransient() { + return this.shadow$getEncodeId() == null; + } + @Override public void bridge$setTransient(final boolean value) { this.impl$transient = value;