Skip to content

Commit 51f061b

Browse files
mfishmakennytv
andauthored
Pass original item ids to custom model data (#1217)
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
1 parent 14b3296 commit 51f061b

File tree

4 files changed

+79
-11
lines changed

4 files changed

+79
-11
lines changed

common/src/main/java/com/viaversion/viabackwards/ViaBackwardsConfig.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public class ViaBackwardsConfig extends Config implements com.viaversion.viaback
4747
private boolean dialogsViaChests;
4848
private DialogStyleConfig dialogStyleConfig;
4949
private boolean codeOfConductAsDialog;
50+
private boolean passOriginalItemNameToResourcePacks;
5051

5152
public ViaBackwardsConfig(File configFile, Logger logger) {
5253
super(configFile, logger);
@@ -75,6 +76,7 @@ private void loadFields() {
7576
dialogsViaChests = getBoolean("dialogs-via-chests", true);
7677
dialogStyleConfig = loadDialogStyleConfig(getSection("dialog-style"));
7778
codeOfConductAsDialog = getBoolean("code-of-conduct-as-dialog", true);
79+
passOriginalItemNameToResourcePacks = getBoolean("pass-original-item-name-to-resource-packs", true);
7880
}
7981

8082
private DialogStyleConfig loadDialogStyleConfig(final ConfigSection section) {
@@ -179,6 +181,11 @@ public boolean codeOfConductAsDialog() {
179181
return codeOfConductAsDialog;
180182
}
181183

184+
@Override
185+
public boolean passOriginalItemNameToResourcePacks() {
186+
return passOriginalItemNameToResourcePacks;
187+
}
188+
182189
@Override
183190
public URL getDefaultConfigURL() {
184191
return getClass().getClassLoader().getResource("assets/viabackwards/config.yml");

common/src/main/java/com/viaversion/viabackwards/api/ViaBackwardsConfig.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,13 @@ public interface ViaBackwardsConfig extends Config {
133133
* @return true if enabled
134134
*/
135135
boolean codeOfConductAsDialog();
136+
137+
/**
138+
* Injects the original vanilla 1.21.4+ item name into custom_model_data strings for resource packs.
139+
* Disable if your server creates custom items using modern items as their base.
140+
* Tip: For server custom items, base them on items in the game before 1.21.4 (e.g. saddle) to ensure compatibility.
141+
*
142+
* @return true if enabled
143+
*/
144+
boolean passOriginalItemNameToResourcePacks();
136145
}

common/src/main/java/com/viaversion/viabackwards/api/rewriters/BackwardsStructuredItemRewriter.java

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.viaversion.nbt.tag.ListTag;
2525
import com.viaversion.nbt.tag.StringTag;
2626
import com.viaversion.nbt.tag.Tag;
27+
import com.viaversion.viabackwards.ViaBackwards;
2728
import com.viaversion.viabackwards.api.BackwardsProtocol;
2829
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
2930
import com.viaversion.viabackwards.api.data.MappedItem;
@@ -40,6 +41,7 @@
4041
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
4142
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
4243
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
44+
import com.viaversion.viaversion.util.ArrayUtil;
4345
import com.viaversion.viaversion.util.Key;
4446
import java.util.ArrayList;
4547
import java.util.List;
@@ -51,9 +53,13 @@ public class BackwardsStructuredItemRewriter<C extends ClientboundPacketType, S
5153
T extends BackwardsProtocol<C, ?, ?, S>> extends StructuredItemRewriter<C, S, T> {
5254

5355
private static final int[] EMPTY_INT_ARRAY = new int[0];
56+
private static final String GLOBAL_MODEL_DATA_MARKER = "VB|injected_cmd";
57+
58+
private final String nbtTagName;
5459

5560
public BackwardsStructuredItemRewriter(T protocol) {
5661
super(protocol);
62+
this.nbtTagName = "VB|" + protocol.getClass().getSimpleName();
5763
}
5864

5965
@Override
@@ -70,17 +76,11 @@ protected void backupInconvertibleData(final UserConnection connection, final It
7076
customTag.putInt(nbtTagName("id"), item.identifier()); // Save original id
7177

7278
// Add custom model data
73-
if (mappedItem.customModelData() != null) {
79+
final boolean addOriginalIdentifier = ViaBackwards.getConfig().passOriginalItemNameToResourcePacks();
80+
if (mappedItem.customModelData() != null || addOriginalIdentifier) {
7481
if (connection.getProtocolInfo().protocolVersion().newerThanOrEqualTo(ProtocolVersion.v1_21_4)) {
75-
if (!dataContainer.has(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4)) {
76-
dataContainer.set(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4, new CustomModelData1_21_4(
77-
new float[]{mappedItem.customModelData().floatValue()},
78-
new boolean[0],
79-
new String[0],
80-
EMPTY_INT_ARRAY
81-
));
82-
}
83-
} else if (!dataContainer.has(StructuredDataKey.CUSTOM_MODEL_DATA1_20_5)) {
82+
addCustomModelData(item, addOriginalIdentifier, mappedItem, customTag);
83+
} else if (mappedItem.customModelData() != null && !dataContainer.has(StructuredDataKey.CUSTOM_MODEL_DATA1_20_5)) {
8484
dataContainer.set(StructuredDataKey.CUSTOM_MODEL_DATA1_20_5, mappedItem.customModelData());
8585
}
8686
}
@@ -92,13 +92,59 @@ protected void backupInconvertibleData(final UserConnection connection, final It
9292
}
9393
}
9494

95+
private void addCustomModelData(final Item item, final boolean addOriginalIdentifier, final MappedItem mappedItem, final CompoundTag customTag) {
96+
final StructuredDataContainer dataContainer = item.dataContainer();
97+
CustomModelData1_21_4 customModelData = dataContainer.get(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4);
98+
if (customModelData == null) {
99+
final String[] strings = addOriginalIdentifier
100+
? new String[]{protocol.getMappingData().getFullItemMappings().identifier(item.identifier())}
101+
: new String[0];
102+
customModelData = new CustomModelData1_21_4(
103+
mappedItem.customModelData() != null ? new float[]{mappedItem.customModelData().floatValue()} : new float[0],
104+
new boolean[0],
105+
strings,
106+
EMPTY_INT_ARRAY
107+
);
108+
dataContainer.set(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4, customModelData);
109+
// Add one global marker and one for this specific version, so it is removed at the correct protocol
110+
customTag.putBoolean(GLOBAL_MODEL_DATA_MARKER, true);
111+
customTag.putBoolean(nbtTagName("added_custom_model_data"), true);
112+
} else if (addOriginalIdentifier && !customTag.contains(GLOBAL_MODEL_DATA_MARKER)) {
113+
final String identifier = protocol.getMappingData().getFullItemMappings().identifier(item.identifier());
114+
dataContainer.set(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4, new CustomModelData1_21_4(
115+
customModelData.floats(), customModelData.booleans(), ArrayUtil.add(customModelData.strings(), identifier), customModelData.colors()
116+
));
117+
customTag.putBoolean(GLOBAL_MODEL_DATA_MARKER, true);
118+
customTag.putString(nbtTagName("injected_custom_model_data"), identifier);
119+
}
120+
}
121+
95122
@Override
96123
protected void restoreBackupData(final Item item, final StructuredDataContainer container, final CompoundTag customData) {
97124
super.restoreBackupData(item, container, customData);
98125
if (removeBackupTag(customData, "id") instanceof final IntTag originalTag) {
99126
item.setIdentifier(originalTag.asInt());
100127
removeCustomTag(container, customData);
101128
}
129+
130+
if (removeBackupTag(customData, "injected_custom_model_data") instanceof StringTag injectedCustomModelData) {
131+
customData.remove(GLOBAL_MODEL_DATA_MARKER);
132+
container.replace(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4, customModelData -> {
133+
final String target = injectedCustomModelData.getValue();
134+
final String[] strings = customModelData.strings();
135+
for (int i = 0; i < strings.length; i++) {
136+
if (strings[i].equals(target)) {
137+
// Remove the injected string
138+
final String[] filteredStrings = ArrayUtil.remove(strings, i);
139+
return new CustomModelData1_21_4(customModelData.floats(), customModelData.booleans(), filteredStrings, customModelData.colors());
140+
}
141+
}
142+
return customModelData;
143+
});
144+
} else if (removeBackupTag(customData, "added_custom_model_data") != null) {
145+
customData.remove(GLOBAL_MODEL_DATA_MARKER);
146+
container.remove(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4);
147+
}
102148
}
103149

104150
protected void saveListTag(CompoundTag tag, ListTag<?> original, String name) {
@@ -313,6 +359,6 @@ protected Holder<SoundEvent> restoreSoundEventHolder(final CompoundTag tag, fina
313359

314360
@Override
315361
public String nbtTagName() {
316-
return "VB|" + protocol.getClass().getSimpleName();
362+
return this.nbtTagName;
317363
}
318364
}

common/src/main/resources/assets/viabackwards/config.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,9 @@ dialog-style:
6868
# Note that this is not supported for clients below 1.21.6 right now due to missing support for
6969
# dialogs during the configuration phase.
7070
code-of-conduct-as-dialog: true
71+
#
72+
# Passes the original vanilla 1.21.4+ item name into custom_model_data strings.
73+
# This allows client resource packs to restore the appearance of newer items entirely missing from this older version.
74+
# Disable if your server creates custom items using modern items as their base.
75+
# Tip: For server custom items, base them on items in the game before 1.21.4 (e.g. saddle) to ensure compatibility.
76+
pass-original-item-name-to-resource-packs: true

0 commit comments

Comments
 (0)