Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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, 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 All @@ -40,6 +41,7 @@
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.rewriter.StructuredItemRewriter;
import com.viaversion.viaversion.util.ArrayUtil;
import com.viaversion.viaversion.util.Key;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -51,9 +53,13 @@ public class BackwardsStructuredItemRewriter<C extends ClientboundPacketType, S
T extends BackwardsProtocol<C, ?, ?, S>> extends StructuredItemRewriter<C, S, T> {

private static final int[] EMPTY_INT_ARRAY = new int[0];
private static final String INJECTED_CMD_MARKER = "VB|injected_cmd";

private final String nbtTagName;

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

@Override
Expand All @@ -70,17 +76,39 @@ 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);
}

if (ViaBackwards.getConfig().passOriginalItemNameToResourcePacks() && mappingData.getFullItemMappings() != null) {
final String identifier = mappingData.getFullItemMappings().identifier(item.identifier());
if (identifier != null && !customTag.contains(INJECTED_CMD_MARKER)) {
boolean exists = false;
for (final String s : customModelData.strings()) {
if (s.equals(identifier)) {
exists = true;
break;
}
}
if (!exists) {
dataContainer.set(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4, new CustomModelData1_21_4(
customModelData.floats(), customModelData.booleans(), ArrayUtil.add(customModelData.strings(), identifier), customModelData.colors()
));
customTag.putString(nbtTagName("injected_cmd_string"), identifier);
customTag.putBoolean(INJECTED_CMD_MARKER, true);
}
}
}
} else if (!dataContainer.has(StructuredDataKey.CUSTOM_MODEL_DATA1_20_5)) {
} 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 +127,35 @@ protected void restoreBackupData(final Item item, final StructuredDataContainer
item.setIdentifier(originalTag.asInt());
removeCustomTag(container, customData);
}

final Tag injectedCmdTag = removeBackupTag(customData, "injected_cmd_string");
if (injectedCmdTag instanceof StringTag stringTag) {
customData.remove(INJECTED_CMD_MARKER);
final CustomModelData1_21_4 customModelData = container.get(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4);
if (customModelData != null && customModelData.strings() != null) {
final String target = stringTag.getValue();
final String[] oldStrings = customModelData.strings();

int index = -1;
for (int i = 0; i < oldStrings.length; i++) {
if (oldStrings[i].equals(target)) {
index = i;
break;
}
}

if (index != -1) {
final String[] newStrings = ArrayUtil.remove(oldStrings, index);
if (newStrings.length == 0 && 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(), newStrings, customModelData.colors()
));
}
}
}
}
}

protected void saveListTag(CompoundTag tag, ListTag<?> original, String name) {
Expand Down Expand Up @@ -313,6 +370,6 @@ protected Holder<SoundEvent> restoreSoundEventHolder(final CompoundTag tag, fina

@Override
public String nbtTagName() {
return "VB|" + protocol.getClass().getSimpleName();
return this.nbtTagName;
}
}
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, 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