1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-08-24 22:42:18 +00:00

Data fixers for turtle owners

This commit is contained in:
Jonathan Coates 2025-06-24 22:58:04 +01:00
parent e3fecb013a
commit 64d10ad45b
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
4 changed files with 83 additions and 3 deletions

View File

@ -9,6 +9,7 @@ import com.mojang.datafixers.DataFixUtils;
import com.mojang.datafixers.DataFixerBuilder;
import com.mojang.datafixers.schemas.Schema;
import dan200.computercraft.shared.datafix.RenamePocketComputerUpgradeFix;
import dan200.computercraft.shared.datafix.TurtleOwnerFix;
import dan200.computercraft.shared.datafix.TurtleUpgradeComponentizationFix;
import net.minecraft.util.datafix.DataFixers;
import net.minecraft.util.datafix.fixes.ItemStackComponentizationFix;
@ -63,6 +64,30 @@ abstract class DataFixersMixin {
return schema;
}
/**
* Register a {@link TurtleOwnerFix} fix.
*
* @param schema The {@code V4424} schema.
* @param builder The current datafixer builder.
* @return The input schema.
*/
@ModifyArg(
method = "addFixers",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/util/datafix/fixes/FeatureFlagRemoveFix;<init>(Lcom/mojang/datafixers/schemas/Schema;Ljava/lang/String;Ljava/util/Set;)V",
ordinal = 4
),
index = 0,
allow = 1
)
@SuppressWarnings("UnusedMethod")
private static Schema addTurtleOwnerFix(Schema schema, @Local DataFixerBuilder builder) {
assertSchemaVersion(schema, DataFixUtils.makeKey(4424, 0));
builder.addFixer(new TurtleOwnerFix(schema));
return schema;
}
@Unique
private static void assertSchemaVersion(Schema schema, int version) {
if (schema.getVersionKey() != version) {

View File

@ -0,0 +1,38 @@
// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package dan200.computercraft.shared.datafix;
import com.mojang.authlib.GameProfile;
import com.mojang.datafixers.TypeRewriteRule;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.serialization.Dynamic;
import net.minecraft.util.datafix.fixes.AbstractUUIDFix;
import net.minecraft.util.datafix.fixes.References;
/**
* A {@link com.mojang.datafixers.DataFix} that updates the turtle owner's {@link GameProfile} to use one more
* consistent with the rest of the game.
*/
public final class TurtleOwnerFix extends AbstractUUIDFix {
public TurtleOwnerFix(Schema outputSchema) {
super(outputSchema, References.BLOCK_ENTITY);
}
@Override
protected TypeRewriteRule makeRule() {
return this.fixTypeEverywhereTyped("BlockEntityUUIDFix", getInputSchema().getType(typeReference), typed -> {
typed = updateNamedChoice(typed, "computercraft:turtle_normal", TurtleOwnerFix::updateTurtle);
return updateNamedChoice(typed, "computercraft:turtle_advanced", TurtleOwnerFix::updateTurtle);
});
}
private static Dynamic<?> updateTurtle(Dynamic<?> turtle) {
return turtle.update("Owner", profile -> profile
.renameField("Name", "name")
.remove("LowerId").remove("UpperId")
.setFieldIfPresent("id", createUUIDFromLongs(profile, "UpperId", "LowerId"))
);
}
}

View File

@ -5,6 +5,8 @@
package dan200.computercraft.shared.turtle.core;
import com.mojang.authlib.GameProfile;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import dan200.computercraft.api.lua.ILuaCallback;
import dan200.computercraft.api.lua.MethodResult;
import dan200.computercraft.api.peripheral.IPeripheral;
@ -26,6 +28,7 @@ import dan200.computercraft.shared.util.Holiday;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Holder;
import net.minecraft.core.UUIDUtil;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.resources.ResourceLocation;
@ -62,6 +65,16 @@ public class TurtleBrain implements TurtleAccessInternal {
private static final String NBT_SLOT = "Slot";
/**
* {@link net.minecraft.world.item.component.ResolvableProfile#CODEC}, but resolving to a {@link GameProfile}
* directly. We don't use {@link ExtraCodecs#GAME_PROFILE}, as that encodes the UUID as a string, not an int array.
*/
private static final Codec<GameProfile> GAME_PROFILE_CODEC = RecordCodecBuilder.create(instance -> instance.group(
UUIDUtil.CODEC.fieldOf("id").forGetter(GameProfile::getId),
ExtraCodecs.PLAYER_NAME.fieldOf("name").forGetter(GameProfile::getName)
)
.apply(instance, GameProfile::new));
private static final int ANIM_DURATION = 8;
private TurtleBlockEntity owner;
@ -160,7 +173,7 @@ public class TurtleBrain implements TurtleAccessInternal {
selectedSlot = nbt.getIntOr(NBT_SLOT, 0);
// Read owner
owningPlayer = nbt.read("Owner", ExtraCodecs.GAME_PROFILE).orElse(null);
owningPlayer = nbt.read("Owner", GAME_PROFILE_CODEC).orElse(null);
}
public void writeToNBT(ValueOutput nbt) {
@ -168,8 +181,7 @@ public class TurtleBrain implements TurtleAccessInternal {
// Write state
nbt.putInt(NBT_SLOT, selectedSlot);
nbt.storeNullable("Owner", ExtraCodecs.GAME_PROFILE, owningPlayer);
// TODO(1.21.6): Data fixer for this.
nbt.storeNullable("Owner", GAME_PROFILE_CODEC, owningPlayer);
}
public void readDescription(ValueInput nbt) {

View File

@ -4,6 +4,7 @@
package dan200.computercraft.gametest
import com.mojang.authlib.GameProfile
import dan200.computercraft.api.ComputerCraftAPI
import dan200.computercraft.api.ComputerCraftTags
import dan200.computercraft.api.detail.ComponentDetailProvider
@ -26,6 +27,7 @@ import dan200.computercraft.shared.peripheral.monitor.MonitorBlock
import dan200.computercraft.shared.peripheral.monitor.MonitorEdgeState
import dan200.computercraft.shared.turtle.apis.TurtleAPI
import dan200.computercraft.shared.turtle.blocks.TurtleBlockEntity
import dan200.computercraft.shared.turtle.core.TurtleBrain
import dan200.computercraft.shared.turtle.core.TurtleCraftCommand
import dan200.computercraft.shared.turtle.items.TurtleItem
import dan200.computercraft.shared.util.WaterloggableHelpers
@ -783,6 +785,9 @@ class Turtle_Test {
val turtleItem = turtleBe.getItem(0)
assertEquals(overlay, TurtleItem.getOverlay(turtleItem))
assertEquals(upgrade, TurtleItem.getUpgrade(turtleItem, TurtleSide.LEFT))
val owner = (turtleBe.access as TurtleBrain).owningPlayer
assertEquals(GameProfile(UUID.fromString("01986ee6-ca3c-3b64-bdcd-02039da5963f"), "Player436"), owner)
}
}