player entity value may become invalid due to respawns. This not only fixes #633, but also other cases where player reference is used over time while player respawns and its instance is recycled.
This commit is contained in:
1 parent
f0a52fc751
commit
d6eb53b6ce
4 files changed
+41
-9
No files matched your search
@@ -5,4 +5,7 @@ import carpet.helpers.EntityPlayerActionPack;
|
|||||||
public interface ServerPlayerEntityInterface
|
public interface ServerPlayerEntityInterface
|
||||||
{
|
{
|
||||||
EntityPlayerActionPack getActionPack();
|
EntityPlayerActionPack getActionPack();
|
||||||
|
void invalidateEntityObjectReference();
|
||||||
|
boolean isInvalidEntityObject();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package carpet.mixins;
|
package carpet.mixins;
|
||||||
|
|
||||||
|
import carpet.fakes.ServerPlayerEntityInterface;
|
||||||
import net.minecraft.server.PlayerManager;
|
import net.minecraft.server.PlayerManager;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
@@ -17,4 +18,11 @@ public class PlayerManager_scarpetEventsMixin
|
|||||||
{
|
{
|
||||||
PLAYER_RESPAWNS.onPlayerEvent(player);
|
PLAYER_RESPAWNS.onPlayerEvent(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject(method = "respawnPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayerEntity;onSpawn()V"))
|
||||||
|
private void invalidatePreviousInstance(ServerPlayerEntity player, boolean alive, CallbackInfoReturnable<ServerPlayerEntity> cir)
|
||||||
|
{
|
||||||
|
((ServerPlayerEntityInterface)player).invalidateEntityObjectReference();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package carpet.mixins;
|
package carpet.mixins;
|
||||||
|
|
||||||
import carpet.fakes.EntityInterface;
|
import carpet.fakes.EntityInterface;
|
||||||
|
import carpet.fakes.ServerPlayerEntityInterface;
|
||||||
import carpet.script.EntityEventsGroup;
|
import carpet.script.EntityEventsGroup;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
@@ -28,8 +29,11 @@ import static carpet.script.CarpetEventServer.Event.PLAYER_FINISHED_USING_ITEM;
|
|||||||
import static carpet.script.CarpetEventServer.Event.STATISTICS;
|
import static carpet.script.CarpetEventServer.Event.STATISTICS;
|
||||||
|
|
||||||
@Mixin(ServerPlayerEntity.class)
|
@Mixin(ServerPlayerEntity.class)
|
||||||
public abstract class ServerPlayerEntity_scarpetEventMixin extends PlayerEntity
|
public abstract class ServerPlayerEntity_scarpetEventMixin extends PlayerEntity implements ServerPlayerEntityInterface
|
||||||
{
|
{
|
||||||
|
// to denote if the player reference is valid
|
||||||
|
|
||||||
|
private boolean isInvalidReference = false;
|
||||||
|
|
||||||
public ServerPlayerEntity_scarpetEventMixin(World world, BlockPos blockPos, float f, GameProfile gameProfile)
|
public ServerPlayerEntity_scarpetEventMixin(World world, BlockPos blockPos, float f, GameProfile gameProfile)
|
||||||
{
|
{
|
||||||
@@ -109,6 +113,17 @@ public abstract class ServerPlayerEntity_scarpetEventMixin extends PlayerEntity
|
|||||||
}
|
}
|
||||||
PLAYER_CHANGES_DIMENSION.onDimensionChange(player, previousLocation, to, previousDimension, destination.getRegistryKey());
|
PLAYER_CHANGES_DIMENSION.onDimensionChange(player, previousLocation, to, previousDimension, destination.getRegistryKey());
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateEntityObjectReference()
|
||||||
|
{
|
||||||
|
isInvalidReference = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isInvalidEntityObject()
|
||||||
|
{
|
||||||
|
return isInvalidReference;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import carpet.fakes.LivingEntityInterface;
|
|||||||
import carpet.fakes.MemoryInterface;
|
import carpet.fakes.MemoryInterface;
|
||||||
import carpet.fakes.MobEntityInterface;
|
import carpet.fakes.MobEntityInterface;
|
||||||
import carpet.fakes.HungerManagerInterface;
|
import carpet.fakes.HungerManagerInterface;
|
||||||
|
import carpet.fakes.ServerPlayerEntityInterface;
|
||||||
import carpet.fakes.ServerPlayerInteractionManagerInterface;
|
import carpet.fakes.ServerPlayerInteractionManagerInterface;
|
||||||
import carpet.helpers.Tracer;
|
import carpet.helpers.Tracer;
|
||||||
import carpet.network.ServerNetworkHandler;
|
import carpet.network.ServerNetworkHandler;
|
||||||
@@ -90,7 +91,7 @@ import static carpet.utils.MobAI.genericJump;
|
|||||||
// TODO: decide whether copy(entity) should duplicate entity in the world.
|
// TODO: decide whether copy(entity) should duplicate entity in the world.
|
||||||
public class EntityValue extends Value
|
public class EntityValue extends Value
|
||||||
{
|
{
|
||||||
private final Entity entity;
|
private Entity entity;
|
||||||
|
|
||||||
public EntityValue(Entity e)
|
public EntityValue(Entity e)
|
||||||
{
|
{
|
||||||
@@ -119,6 +120,11 @@ public class EntityValue extends Value
|
|||||||
|
|
||||||
public Entity getEntity()
|
public Entity getEntity()
|
||||||
{
|
{
|
||||||
|
if (entity instanceof ServerPlayerEntity && ((ServerPlayerEntityInterface)entity).isInvalidEntityObject())
|
||||||
|
{
|
||||||
|
ServerPlayerEntity newPlayer = entity.getServer().getPlayerManager().getPlayer(entity.getUuid());
|
||||||
|
if (newPlayer != null) entity = newPlayer;
|
||||||
|
}
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,7 +176,7 @@ public class EntityValue extends Value
|
|||||||
@Override
|
@Override
|
||||||
public String getString()
|
public String getString()
|
||||||
{
|
{
|
||||||
return entity.getName().getString();
|
return getEntity().getName().getString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -184,7 +190,7 @@ public class EntityValue extends Value
|
|||||||
{
|
{
|
||||||
if (v instanceof EntityValue)
|
if (v instanceof EntityValue)
|
||||||
{
|
{
|
||||||
return entity.getEntityId()==((EntityValue) v).entity.getEntityId();
|
return getEntity().getEntityId()==((EntityValue) v).getEntity().getEntityId();
|
||||||
}
|
}
|
||||||
return super.equals((Value)v);
|
return super.equals((Value)v);
|
||||||
}
|
}
|
||||||
@@ -220,7 +226,7 @@ public class EntityValue extends Value
|
|||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
return entity.hashCode();
|
return getEntity().hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityClassDescriptor getEntityDescriptor(String who, MinecraftServer server)
|
public static EntityClassDescriptor getEntityDescriptor(String who, MinecraftServer server)
|
||||||
@@ -374,7 +380,7 @@ public class EntityValue extends Value
|
|||||||
throw new InternalExpressionException("Unknown entity feature: "+what);
|
throw new InternalExpressionException("Unknown entity feature: "+what);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return featureAccessors.get(what).apply(entity, arg);
|
return featureAccessors.get(what).apply(getEntity(), arg);
|
||||||
}
|
}
|
||||||
catch (NullPointerException npe)
|
catch (NullPointerException npe)
|
||||||
{
|
{
|
||||||
@@ -835,7 +841,7 @@ public class EntityValue extends Value
|
|||||||
throw new InternalExpressionException("Unknown entity action: " + what);
|
throw new InternalExpressionException("Unknown entity action: " + what);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
featureModifiers.get(what).accept(entity, toWhat);
|
featureModifiers.get(what).accept(getEntity(), toWhat);
|
||||||
}
|
}
|
||||||
catch (NullPointerException npe)
|
catch (NullPointerException npe)
|
||||||
{
|
{
|
||||||
@@ -1468,7 +1474,7 @@ public class EntityValue extends Value
|
|||||||
EntityEventsGroup.Event event = EntityEventsGroup.Event.byName.get(eventName);
|
EntityEventsGroup.Event event = EntityEventsGroup.Event.byName.get(eventName);
|
||||||
if (event == null)
|
if (event == null)
|
||||||
throw new InternalExpressionException("Unknown entity event: " + eventName);
|
throw new InternalExpressionException("Unknown entity event: " + eventName);
|
||||||
((EntityInterface)entity).getEventContainer().addEvent(event, cc.host, fun, args);
|
((EntityInterface)getEntity()).getEventContainer().addEvent(event, cc.host, fun, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1477,7 +1483,7 @@ public class EntityValue extends Value
|
|||||||
if (!force) throw new NBTSerializableValue.IncompatibleTypeException(this);
|
if (!force) throw new NBTSerializableValue.IncompatibleTypeException(this);
|
||||||
CompoundTag tag = new CompoundTag();
|
CompoundTag tag = new CompoundTag();
|
||||||
tag.put("Data", getEntity().toTag( new CompoundTag()));
|
tag.put("Data", getEntity().toTag( new CompoundTag()));
|
||||||
tag.put("Name", StringTag.of(Registry.ENTITY_TYPE.getId(entity.getType()).toString()));
|
tag.put("Name", StringTag.of(Registry.ENTITY_TYPE.getId(getEntity().getType()).toString()));
|
||||||
return tag;
|
return tag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user