1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-08-27 16:02:17 +00:00

[TODO] Fix players not getting advancements when they own turtles

This commit is contained in:
Merith-TK 2021-02-22 17:32:26 -08:00
parent 5d91491ec7
commit 592b83e784
4 changed files with 55 additions and 11 deletions

View File

@ -208,3 +208,22 @@ Remove superfluous imports
Hah, this is embarassing
```
[TODO] [M3R1-01] Code has been applied, players still dont get achievments
```
f6160bdc57b3d9850607c2c7c2ce9734b4963478
Fix players not getting advancements when they own turtles
When we construct a new ServerPlayerEntity (and thus TurtlePlayer), we
get the current (global) advancement state and call .setPlayer() on it.
As grantCriterion blocks FakePlayers from getting advancements, this
means a player will no longer receive any advancements, as the "wrong"
player object is being consulted.
As a temporary work around, we attempt to restore the previous player to
the advancement store. I'll try to upstream something into Forge to
resolve this properly.
Fixes #564
```

View File

@ -135,7 +135,7 @@ public interface ITurtleAccess {
*
* @return This turtle's owner.
*/
@Nonnull
@Nullable
GameProfile getOwningPlayer();
/**

View File

@ -19,6 +19,7 @@ import java.util.UUID;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.google.common.base.Objects;
import com.mojang.authlib.GameProfile;
@ -341,7 +342,7 @@ public class TurtleBrain implements ITurtleAccess {
}
}
@Nonnull
@Nullable
@Override
public GameProfile getOwningPlayer() {
return this.m_owningPlayer;

View File

@ -33,6 +33,7 @@ import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
@ -42,13 +43,33 @@ import net.minecraft.util.math.Vec3d;
@SuppressWarnings ("EntityConstructor")
public final class TurtlePlayer extends FakePlayer {
private static final GameProfile DEFAULT_PROFILE = new GameProfile(UUID.fromString("0d0c4ca0-4ff1-11e4-916c-0800200c9a66"), "[ComputerCraft]");
private TurtlePlayer(ITurtleAccess turtle) {
super((ServerWorld) turtle.getWorld(), getProfile(turtle.getOwningPlayer()));
this.networkHandler = new FakeNetHandler(this);
this.setState(turtle);
// TODO [M3R1-01] Fix Turtle not giving player achievement for actions
private TurtlePlayer( ServerWorld world, GameProfile name )
{
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.networkHandler = 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().getPlayerManager().getPlayer(player.getUuid());
if( actualPlayer != null ) player.getAdvancementTracker().setOwner(actualPlayer);
}
return player;
}
private static GameProfile getProfile(@Nullable GameProfile profile) {
return profile != null && profile.isComplete() ? profile : DEFAULT_PROFILE;
}
@ -70,14 +91,17 @@ public final class TurtlePlayer extends FakePlayer {
}
public static TurtlePlayer get(ITurtleAccess access) {
if (!(access instanceof TurtleBrain)) {
return new TurtlePlayer(access);
}
ServerWorld world = (ServerWorld) access.getWorld();
if( !(access instanceof TurtleBrain) ) return create( access );
/*if (!(access instanceof TurtleBrain)) {
return new TurtlePlayer(world, access.getOwningPlayer());
}*/
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 {
player.setState(access);
}