Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class ViaBackwardsConfig extends Config implements com.viaversion.viaback
private boolean dialogsViaChests;
private DialogStyleConfig dialogStyleConfig;
private boolean codeOfConductAsDialog;
private boolean passOriginalItemNameToResourcePacks;

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

private DialogStyleConfig loadDialogStyleConfig(final ConfigSection section) {
Expand Down Expand Up @@ -179,6 +181,11 @@ public boolean codeOfConductAsDialog() {
return codeOfConductAsDialog;
}

@Override
public boolean passOriginalItemNameToResourcePacks() {
return passOriginalItemNameToResourcePacks;
}

@Override
public URL getDefaultConfigURL() {
return getClass().getClassLoader().getResource("assets/viabackwards/config.yml");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,13 @@ public interface ViaBackwardsConfig extends Config {
* @return true if enabled
*/
boolean codeOfConductAsDialog();

/**
* Injects the original vanilla 1.21.4+ item name into custom_model_data strings for resource packs.
* Disable if your server creates custom items using modern items as their base.
* Tip: For server custom items, always base them on items in the game before 1.21.4 (e.g. saddle) to ensure compatibility.
*
* @return true if enabled
*/
boolean passOriginalItemNameToResourcePacks();
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
import com.viaversion.viabackwards.api.data.MappedItem;
Expand Down Expand Up @@ -70,17 +71,42 @@ protected void backupInconvertibleData(final UserConnection connection, final It
customTag.putInt(nbtTagName("id"), item.identifier()); // Save original id

// Add custom model data
if (mappedItem.customModelData() != null) {
if (mappedItem.customModelData() != null || ViaBackwards.getConfig().passOriginalItemNameToResourcePacks()) {
if (connection.getProtocolInfo().protocolVersion().newerThanOrEqualTo(ProtocolVersion.v1_21_4)) {
if (!dataContainer.has(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4)) {
dataContainer.set(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4, new CustomModelData1_21_4(
new float[]{mappedItem.customModelData().floatValue()},
CustomModelData1_21_4 customModelData = dataContainer.get(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4);
if (customModelData == null) {
customModelData = new CustomModelData1_21_4(
mappedItem.customModelData() != null ? new float[]{mappedItem.customModelData().floatValue()} : new float[0],
new boolean[0],
new String[0],
EMPTY_INT_ARRAY
));
);
dataContainer.set(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4, customModelData);
}
} else if (!dataContainer.has(StructuredDataKey.CUSTOM_MODEL_DATA1_20_5)) {

if (ViaBackwards.getConfig().passOriginalItemNameToResourcePacks() && mappingData.getFullItemMappings() != null) {
final String identifier = mappingData.getFullItemMappings().identifier(item.identifier());
if (identifier != null) {
final String injection = "viabackwards:" + Key.stripMinecraftNamespace(identifier);
boolean exists = false;
Comment thread
mfishma marked this conversation as resolved.
Outdated
for (final String s : customModelData.strings()) {
if (s.equals(injection)) {
exists = true;
break;
}
}
if (!exists) {
final String[] newStrings = new String[customModelData.strings().length + 1];
System.arraycopy(customModelData.strings(), 0, newStrings, 0, customModelData.strings().length);
newStrings[customModelData.strings().length] = injection;
Comment thread
mfishma marked this conversation as resolved.
Outdated
dataContainer.set(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4, new CustomModelData1_21_4(
customModelData.floats(), customModelData.booleans(), newStrings, customModelData.colors()
));
customTag.putBoolean(nbtTagName("injected_cmd_string"), true);
}
}
}
} else if (mappedItem.customModelData() != null && !dataContainer.has(StructuredDataKey.CUSTOM_MODEL_DATA1_20_5)) {
dataContainer.set(StructuredDataKey.CUSTOM_MODEL_DATA1_20_5, mappedItem.customModelData());
}
}
Expand All @@ -99,6 +125,22 @@ protected void restoreBackupData(final Item item, final StructuredDataContainer
item.setIdentifier(originalTag.asInt());
removeCustomTag(container, customData);
}

if (removeBackupTag(customData, "injected_cmd_string") != null) {
final CustomModelData1_21_4 customModelData = container.get(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4);
if (customModelData != null && customModelData.strings() != null) {
final List<String> strings = new java.util.ArrayList<>(java.util.Arrays.asList(customModelData.strings()));
if (strings.removeIf(s -> s.startsWith("viabackwards:"))) {
if (strings.isEmpty() && customModelData.floats().length == 0 && customModelData.booleans().length == 0 && customModelData.colors().length == 0) {
container.remove(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4);
} else {
container.set(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4, new CustomModelData1_21_4(
customModelData.floats(), customModelData.booleans(), strings.toArray(new String[0]), customModelData.colors()
));
}
}
}
}
}

protected void saveListTag(CompoundTag tag, ListTag<?> original, String name) {
Expand Down
6 changes: 6 additions & 0 deletions common/src/main/resources/assets/viabackwards/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,9 @@ dialog-style:
# Note that this is not supported for clients below 1.21.6 right now due to missing support for
# dialogs during the configuration phase.
code-of-conduct-as-dialog: true
#
# Passes the original vanilla 1.21.4+ item name into custom_model_data strings.
# This allows client resource packs to restore the appearance of newer items entirely missing from this older version.
# Disable if your server creates custom items using modern items as their base.
# Tip: For server custom items, always base them on items in the game before 1.21.4 (e.g. saddle) to ensure compatibility.
pass-original-item-name-to-resource-packs: true