diff --git a/build.gradle b/build.gradle index eab59f562..77998bae4 100644 --- a/build.gradle +++ b/build.gradle @@ -9,7 +9,7 @@ } dependencies { classpath 'com.google.code.gson:gson:2.8.1' - classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.179' + classpath 'net.minecraftforge.gradle:ForgeGradle:3.0.187' classpath 'net.sf.proguard:proguard-gradle:6.1.0beta2' classpath 'org.ajoberstar.grgit:grgit-gradle:3.0.0' } diff --git a/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java b/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java index 53b176dbf..85752b15a 100644 --- a/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java +++ b/src/main/java/dan200/computercraft/api/turtle/ITurtleAccess.java @@ -139,7 +139,7 @@ public interface ITurtleAccess * * @return This turtle's owner. */ - @Nonnull + @Nullable GameProfile getOwningPlayer(); /** diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java index 31b363aa3..373d0787c 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtleBrain.java @@ -45,6 +45,7 @@ import net.minecraftforge.items.wrapper.InvWrapper; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.*; import java.util.concurrent.TimeUnit; @@ -598,7 +599,7 @@ public void setOwningPlayer( GameProfile profile ) m_owningPlayer = profile; } - @Nonnull + @Nullable @Override public GameProfile getOwningPlayer() { diff --git a/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java b/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java index 86e5f76ad..4b60932e3 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java +++ b/src/main/java/dan200/computercraft/shared/turtle/core/TurtlePlayer.java @@ -17,6 +17,7 @@ import net.minecraft.entity.EntityType; import net.minecraft.entity.Pose; import net.minecraft.entity.passive.horse.AbstractHorseEntity; +import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.container.INamedContainerProvider; import net.minecraft.item.ItemStack; @@ -41,11 +42,30 @@ public final class TurtlePlayer extends FakePlayer "[ComputerCraft]" ); - private TurtlePlayer( ITurtleAccess turtle ) + private TurtlePlayer( ServerWorld world, GameProfile name ) { - super( (ServerWorld) turtle.getWorld(), getProfile( turtle.getOwningPlayer() ) ); - this.connection = new FakeNetHandler( this ); - setState( turtle ); + super( world, name ); + } + + private static TurtlePlayer create( ITurtleAccess turtle ) + { + ServerWorld world = (ServerWorld) turtle.getWorld(); + GameProfile profile = turtle.getOwningPlayer(); + + TurtlePlayer player = new TurtlePlayer( world, getProfile( profile ) ); + player.connection = new FakeNetHandler( player ); + player.setState( turtle ); + + if( profile != null && profile.getId() != null ) + { + // Constructing a player overrides the "active player" variable in advancements. As fake players cannot + // get advancements, this prevents a normal player who has placed a turtle from getting advancements. + // We try to locate the "actual" player and restore them. + ServerPlayerEntity actualPlayer = world.getServer().getPlayerList().getPlayerByUUID( profile.getId() ); + if( actualPlayer != null ) player.getAdvancements().setPlayer( actualPlayer ); + } + + return player; } private static GameProfile getProfile( @Nullable GameProfile profile ) @@ -72,14 +92,14 @@ private void setState( ITurtleAccess turtle ) public static TurtlePlayer get( ITurtleAccess access ) { - if( !(access instanceof TurtleBrain) ) return new TurtlePlayer( access ); + if( !(access instanceof TurtleBrain) ) return create( access ); TurtleBrain brain = (TurtleBrain) access; TurtlePlayer player = brain.m_cachedPlayer; if( player == null || player.getGameProfile() != getProfile( access.getOwningPlayer() ) || player.getEntityWorld() != access.getWorld() ) { - player = brain.m_cachedPlayer = new TurtlePlayer( brain ); + player = brain.m_cachedPlayer = create( brain ); } else {