Skip to content

Commit

Permalink
Add item stack componentization data fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
haykam821 authored and Patbox committed Nov 30, 2024
1 parent 542d6e6 commit 9ce20b6
Show file tree
Hide file tree
Showing 5 changed files with 351 additions and 0 deletions.
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ dependencies {
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
testImplementation "net.fabricmc:fabric-loader-junit:${project.loader_version}"

modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"

Expand All @@ -41,6 +42,10 @@ dependencies {
modCompileOnly "dev.gegy:player-roles-api:1.6.13"
}

test {
useJUnitPlatform()
}

processResources {
inputs.property "version", project.version

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package xyz.nucleoid.extras.mixin.lobby;

import com.mojang.serialization.Dynamic;
import net.minecraft.datafixer.fix.ItemStackComponentizationFix;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.Set;

@Mixin(ItemStackComponentizationFix.class)
public class ItemStackComponentizationFixMixin {
@Unique
private static final Set<String> TATER_BOX_ITEMS = Set.of(
"nucleoid_extras:tater_box",
"nucleoid_extras:creative_tater_box"
);

@Inject(method = "fixStack", at = @At("TAIL"))
private static void fixNucleoidExtrasStack(ItemStackComponentizationFix.StackData data, Dynamic<?> dynamic, CallbackInfo ci) {
if (data.itemEquals("nucleoid_extras:game_portal_opener")) {
data.getAndRemove("GamePortal").result().ifPresent(gamePortalId -> {
var component = dynamic.emptyMap().set("game_portal_id", gamePortalId);
data.setComponent("nucleoid_extras:game_portal", component);
});
} else if (data.itemMatches(TATER_BOX_ITEMS)) {
data.getAndRemove("SelectedTater").result().ifPresent(gamePortalId -> {
var component = dynamic.emptyMap().set("tater", gamePortalId);
data.setComponent("nucleoid_extras:tater_selection", component);
});
} else if (data.itemEquals("nucleoid_extras:tater_guidebook")) {
data.getAndRemove("tater_positions").result().ifPresent(positions -> {
var component = dynamic.emptyMap().set("positions", positions);
data.setComponent("nucleoid_extras:tater_positions", component);
});
} else if (data.itemEquals("nucleoid_extras:launch_feather")) {
Dynamic<?> component = dynamic.emptyMap();

component = data.moveToComponent("Pitch", component, "pitch");
component = data.moveToComponent("Power", component, "power");

if (!component.equals(dynamic.emptyMap())) {
data.setComponent("nucleoid_extras:launcher", component);
}
}
}
}
2 changes: 2 additions & 0 deletions src/main/resources/extras.accesswidener
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ accessible method net/minecraft/block/entity/BellBlockEntity applyGlowToRaide
accessible method net/minecraft/block/entity/BellBlockEntity applyParticlesToRaiders (Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Ljava/util/List;)V

extendable method net/minecraft/block/AbstractBlock getTranslationKey ()Ljava/lang/String;

accessible class net/minecraft/datafixer/fix/ItemStackComponentizationFix$StackData
1 change: 1 addition & 0 deletions src/main/resources/extras.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"TextCodecMixin",
"debug.EntityMixin",
"lobby.ArmorStandEntityAccessor",
"lobby.ItemStackComponentizationFixMixin",
"lobby.LivingEntityAccessor",
"lobby.ServerChunkLoadingManagerAccessor",
"lobby.ServerPlayerEntityMixin",
Expand Down
294 changes: 294 additions & 0 deletions src/test/java/xyz/nucleoid/extras/test/DataFixTests.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
package xyz.nucleoid.extras.test;

import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.serialization.Dynamic;
import net.minecraft.Bootstrap;
import net.minecraft.SharedConstants;
import net.minecraft.datafixer.Schemas;
import net.minecraft.datafixer.TypeReferences;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtOps;
import net.minecraft.nbt.StringNbtReader;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class DataFixTests {
private static final int DATA_VERSION_1_20_4 = 3700;
private static final int DATA_VERSION_1_21_3 = 4082;


@BeforeAll
public static void beforeAll() {
SharedConstants.createGameVersion();
Bootstrap.initialize();
}

@Test
public void testGamePortalOpenerWithoutIdComponentization() {
assertItemStackComponentization("""
{
id: "nucleoid_extras:game_portal_opener",
Count: 1
}
""", """
{
id: "nucleoid_extras:game_portal_opener",
count: 1
}
""");
}

@Test
public void testGamePortalOpenerComponentization() {
assertItemStackComponentization("""
{
id: "nucleoid_extras:game_portal_opener",
Count: 1,
tag: {
GamePortal: "nucleoid:top_level/navigator"
}
}
""", """
{
id: "nucleoid_extras:game_portal_opener",
count: 1,
components: {
"nucleoid_extras:game_portal": {
game_portal_id: "nucleoid:top_level/navigator"
}
}
}
""");
}

@Test
public void testTaterBoxWithoutSelectionComponentization() {
assertItemStackComponentization("""
{
id: "nucleoid_extras:tater_box",
Count: 1
}
""", """
{
id: "nucleoid_extras:tater_box",
count: 1
}
""");
}

@Test
public void testTaterBoxComponentization() {
assertItemStackComponentization("""
{
id: "nucleoid_extras:tater_box",
Count: 1,
tag: {
SelectedTater: "nucleoid_extras:tiny_potato"
}
}
""", """
{
id: "nucleoid_extras:tater_box",
count: 1,
components: {
"nucleoid_extras:tater_selection": {
tater: "nucleoid_extras:tiny_potato"
}
}
}
""");
}

@Test
public void testTaterBoxWithLegacyTatersComponentization() {
assertItemStackComponentization("""
{
id: "nucleoid_extras:tater_box",
Count: 1,
tag: {
SelectedTater: "nucleoid_extras:botanical_tater",
Taters: [
"nucleoid_extras:tiny_potato",
"nucleoid_extras:botanical_tater"
]
}
}
""", """
{
id: "nucleoid_extras:tater_box",
count: 1,
components: {
"nucleoid_extras:tater_selection": {
tater: "nucleoid_extras:botanical_tater"
},
"minecraft:custom_data": {
Taters: [
"nucleoid_extras:tiny_potato",
"nucleoid_extras:botanical_tater"
]
}
}
}
""");
}

@Test
public void testCreativeTaterBoxComponentization() {
assertItemStackComponentization("""
{
id: "nucleoid_extras:creative_tater_box",
Count: 1,
tag: {
SelectedTater: "nucleoid_extras:bedrock_tater"
}
}
""", """
{
id: "nucleoid_extras:creative_tater_box",
count: 1,
components: {
"nucleoid_extras:tater_selection": {
tater: "nucleoid_extras:bedrock_tater"
}
}
}
""");
}

@Test
public void testTaterGuidebookComponentization() {
assertItemStackComponentization("""
{
id: "nucleoid_extras:tater_guidebook",
Count: 1,
tag: {
tater_positions: {
"nucleoid_extras:irritater": [
{X: 0, Y: 1, Z: 2}
]
}
}
}
""", """
{
id: "nucleoid_extras:tater_guidebook",
count: 1,
components: {
"nucleoid_extras:tater_positions": {
positions: {
"nucleoid_extras:irritater": [
{X: 0, Y: 1, Z: 2}
]
}
}
}
}
""");
}

@Test
public void testDefaultLaunchFeatherComponentization() {
assertItemStackComponentization("""
{
id: "nucleoid_extras:launch_feather",
Count: 1
}
""", """
{
id: "nucleoid_extras:launch_feather",
count: 1
}
""");
}

@Test
public void testLaunchFeatherWithPitchComponentization() {
assertItemStackComponentization("""
{
id: "nucleoid_extras:launch_feather",
Count: 1,
tag: {
Pitch: 20.1
}
}
""", """
{
id: "nucleoid_extras:launch_feather",
count: 1,
components: {
"nucleoid_extras:launcher": {
pitch: 20.1
}
}
}
""");
}

@Test
public void testLaunchFeatherWithPowerComponentization() {
assertItemStackComponentization("""
{
id: "nucleoid_extras:launch_feather",
Count: 1,
tag: {
Power: 5.2
}
}
""", """
{
id: "nucleoid_extras:launch_feather",
count: 1,
components: {
"nucleoid_extras:launcher": {
power: 5.2
}
}
}
""");
}

@Test
public void testLaunchFeatherWithPitchAndPowerComponentization() {
assertItemStackComponentization("""
{
id: "nucleoid_extras:launch_feather",
Count: 1,
tag: {
Pitch: 18.3,
Power: 4.6
}
}
""", """
{
id: "nucleoid_extras:launch_feather",
count: 1,
components: {
"nucleoid_extras:launcher": {
pitch: 18.3,
power: 4.6
}
}
}
""");
}

private static void assertItemStackComponentization(String oldNbtString, String newNbtString) {
var oldNbt = parseNbtString("oldNbt", oldNbtString);
var newNbt = parseNbtString("newNbt", newNbtString);

var input = new Dynamic<>(NbtOps.INSTANCE, oldNbt);
var output = Schemas.getFixer().update(TypeReferences.ITEM_STACK, input, DATA_VERSION_1_20_4, DATA_VERSION_1_21_3);

assertEquals(newNbt, output.getValue());
}

private static NbtCompound parseNbtString(String name, String string) {
try {
return StringNbtReader.parse(string);
} catch (CommandSyntaxException e) {
throw new RuntimeException("Failed to parse " + name, e);
}
}
}

0 comments on commit 9ce20b6

Please sign in to comment.