Fix 1.21 enchantment remapping

Fixes #795
This commit is contained in:
Nassim Jahnke 2024-06-20 13:13:50 +02:00
parent 418357d8eb
commit 38af6f883b
No known key found for this signature in database
GPG Key ID: EF6771C01F6EF02F
2 changed files with 28 additions and 10 deletions

View File

@ -30,7 +30,6 @@ import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
import com.viaversion.viaversion.libs.fastutil.ints.Int2IntMap;
import com.viaversion.viaversion.libs.fastutil.ints.IntIntPair;
import com.viaversion.viaversion.libs.fastutil.objects.ObjectIterator;
import com.viaversion.viaversion.rewriter.IdRewriteFunction;
import com.viaversion.viaversion.util.ComponentUtil;
@ -86,20 +85,20 @@ public class StructuredEnchantmentRewriter {
boolean changed = false;
final ObjectIterator<Int2IntMap.Entry> iterator = enchantments.enchantments().int2IntEntrySet().iterator();
final List<IntIntPair> updatedIds = new ArrayList<>();
final List<PendingIdChange> updatedIds = new ArrayList<>();
while (iterator.hasNext()) {
final Int2IntMap.Entry entry = iterator.next();
final int id = entry.getIntKey();
final int mappedId = rewriteFunction.rewrite(id);
final int level = entry.getIntValue();
if (mappedId != -1) {
if (rewriteIds) {
// Update the map after to iteration to preserve the current ids before possibly saving the original, avoid CME
updatedIds.add(IntIntPair.of(id, mappedId));
updatedIds.add(new PendingIdChange(id, mappedId, level));
}
continue;
}
final int level = entry.getIntValue();
final Tag description = descriptionSupplier.get(id, level);
if (description != null) {
if (!changed) {
@ -113,9 +112,12 @@ public class StructuredEnchantmentRewriter {
}
}
for (final IntIntPair pair : updatedIds) {
final int level = enchantments.enchantments().remove(pair.firstInt());
enchantments.add(pair.secondInt(), level);
// Remove all first, then add the new ones
for (final PendingIdChange change : updatedIds) {
enchantments.remove(change.id());
}
for (final PendingIdChange change : updatedIds) {
enchantments.add(change.mappedId(), change.level());
}
if (loreToAdd.isEmpty()) {
@ -198,4 +200,7 @@ public class StructuredEnchantmentRewriter {
Tag get(int id, int level);
}
private record PendingIdChange(int id, int mappedId, int level) {
}
}

View File

@ -48,6 +48,7 @@ import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.IdRewriteFunction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.viaversion.viaversion.protocols.v1_20_5to1_21.rewriter.BlockItemPacketRewriter1_21.downgradeItemData;
import static com.viaversion.viaversion.protocols.v1_20_5to1_21.rewriter.BlockItemPacketRewriter1_21.updateItemData;
@ -186,7 +187,8 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe
}
final Enchantments enchantments = enchantmentsData.value();
for (final Int2IntMap.Entry entry : new ArrayList<>(enchantments.enchantments().int2IntEntrySet())) {
final List<PendingIdChange> updatedIds = new ArrayList<>();
for (final Int2IntMap.Entry entry : enchantments.enchantments().int2IntEntrySet()) {
final int id = entry.getIntKey();
final String enchantmentKey = Enchantments1_20_5.idToKey(id);
if (enchantmentKey == null) {
@ -195,9 +197,20 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe
final int mappedId = storage.enchantments().keyToId(enchantmentKey);
if (id != mappedId) {
enchantments.enchantments().remove(id);
enchantments.enchantments().put(mappedId, entry.getIntValue());
final int level = entry.getIntValue();
updatedIds.add(new PendingIdChange(id, mappedId, level));
}
}
// Remove first, then add updated entries
for (final PendingIdChange change : updatedIds) {
enchantments.remove(change.id);
}
for (final PendingIdChange change : updatedIds) {
enchantments.add(change.mappedId, change.level);
}
}
private record PendingIdChange(int id, int mappedId, int level) {
}
}