mirror of
https://github.com/ViaVersion/ViaBackwards.git
synced 2026-11-04 17:00:16 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6363cd38ab | ||
|
|
5ca359b287 | ||
|
|
c18c670bdb | ||
|
|
345406ecae | ||
|
|
4a159bf16a | ||
|
|
6a2482f42f | ||
|
|
8075d49ad2 | ||
|
|
36aecf3444 | ||
|
|
f0aa7d9dae | ||
|
|
b63e031662 | ||
|
|
8825ef0f44 | ||
|
|
eea2687e66 | ||
|
|
712f656a3a | ||
|
|
181a0cb7c1 | ||
|
|
b367037cef | ||
|
|
b90b573f1d | ||
|
|
74aeadd688 | ||
|
|
6f27988cf6 | ||
|
|
81aad86d9f | ||
|
|
1e7dbf38fd | ||
|
|
0404184e15 | ||
|
|
64a7d9f8bd | ||
|
|
924346882c | ||
|
|
1d7332101f | ||
|
|
30e63ebc3b | ||
|
|
217c9459f5 | ||
|
|
ead2c6f330 | ||
|
|
1a972da613 | ||
|
|
44dbbf37e2 | ||
|
|
def010c2bf | ||
|
|
75744d5525 |
No files matched your search
@@ -23,8 +23,15 @@ jobs:
|
||||
distribution: 'temurin'
|
||||
java-version: 17
|
||||
check-latest: true
|
||||
- name: Publish
|
||||
- name: Build
|
||||
run: ./gradlew build
|
||||
- name: Publish to Hangar
|
||||
env:
|
||||
HANGAR_TOKEN: ${{ secrets.HANGAR_TOKEN }}
|
||||
run: ./gradlew publishAllPublicationsToHangar --stacktrace
|
||||
continue-on-error: true
|
||||
- name: Publish to Modrinth
|
||||
env:
|
||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
||||
run: ./gradlew build modrinth publishAllPublicationsToHangar --refresh-dependencies --stacktrace
|
||||
run: ./gradlew modrinth --stacktrace
|
||||
continue-on-error: true
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
# Security Policy
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you discover a **security vulnerability**, please **do not** open a public issue. Instead, use one of the following **confidential contact methods**:
|
||||
|
||||
* **Email:** [security@viaversion.com](mailto:security@viaversion.com)
|
||||
* **Discord:** Join our [Discord server](https://discord.gg/viaversion) and visit the [#exploit-report](https://discord.com/channels/316206679014244363/1388847764137316485) channel for further instructions.
|
||||
|
||||
If your issue is **not security-related** (e.g., bug reports, feature requests, or usage questions), please use the [GitHub Issues page](https://github.com/ViaVersion/ViaBackwards/issues) or contact us via the [Discord server](https://discord.gg/viaversion).
|
||||
@@ -8,5 +8,5 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
// version must be manually kept in sync with the one in root project settings.gradle.kts
|
||||
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.6")
|
||||
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.8")
|
||||
}
|
||||
@@ -21,48 +21,50 @@ package com.viaversion.viabackwards.api;
|
||||
import com.viaversion.viabackwards.ViaBackwards;
|
||||
import com.viaversion.viabackwards.ViaBackwardsConfig;
|
||||
import com.viaversion.viabackwards.api.data.TranslatableMappings;
|
||||
import com.viaversion.viabackwards.protocol.v1_11to1_10.Protocol1_11To1_10;
|
||||
import com.viaversion.viabackwards.protocol.v1_12to1_11_1.Protocol1_12To1_11_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_10to1_9_3.Protocol1_10To1_9_3;
|
||||
import com.viaversion.viabackwards.protocol.v1_11_1to1_11.Protocol1_11_1To1_11;
|
||||
import com.viaversion.viabackwards.protocol.v1_12_2to1_12_1.Protocol1_12_2To1_12_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.Protocol1_13To1_12_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_11to1_10.Protocol1_11To1_10;
|
||||
import com.viaversion.viabackwards.protocol.v1_12_1to1_12.Protocol1_12_1To1_12;
|
||||
import com.viaversion.viabackwards.protocol.v1_13_2to1_13_1.Protocol1_13_2To1_13_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_14to1_13_2.Protocol1_14To1_13_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_12_2to1_12_1.Protocol1_12_2To1_12_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_12to1_11_1.Protocol1_12To1_11_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_13_1to1_13.Protocol1_13_1To1_13;
|
||||
import com.viaversion.viabackwards.protocol.v1_13_2to1_13_1.Protocol1_13_2To1_13_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.Protocol1_13To1_12_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_14_1to1_14.Protocol1_14_1To1_14;
|
||||
import com.viaversion.viabackwards.protocol.v1_14_2to1_14_1.Protocol1_14_2To1_14_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_14_3to1_14_2.Protocol1_14_3To1_14_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_14_4to1_14_3.Protocol1_14_4To1_14_3;
|
||||
import com.viaversion.viabackwards.protocol.v1_15to1_14_4.Protocol1_15To1_14_4;
|
||||
import com.viaversion.viabackwards.protocol.v1_14_1to1_14.Protocol1_14_1To1_14;
|
||||
import com.viaversion.viabackwards.protocol.v1_15_2to1_15_1.Protocol1_15_2To1_15_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_16to1_15_2.Protocol1_16To1_15_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_14to1_13_2.Protocol1_14To1_13_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_15_1to1_15.Protocol1_15_1To1_15;
|
||||
import com.viaversion.viabackwards.protocol.v1_15_2to1_15_1.Protocol1_15_2To1_15_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_15to1_14_4.Protocol1_15To1_14_4;
|
||||
import com.viaversion.viabackwards.protocol.v1_16_1to1_16.Protocol1_16_1To1_16;
|
||||
import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.Protocol1_16_2To1_16_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_16_3to1_16_2.Protocol1_16_3To1_16_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_16_4to1_16_3.Protocol1_16_4To1_16_3;
|
||||
import com.viaversion.viabackwards.protocol.v1_17to1_16_4.Protocol1_17To1_16_4;
|
||||
import com.viaversion.viabackwards.protocol.v1_16_1to1_16.Protocol1_16_1To1_16;
|
||||
import com.viaversion.viabackwards.protocol.v1_18to1_17_1.Protocol1_18To1_17_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_16to1_15_2.Protocol1_16To1_15_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_17_1to1_17.Protocol1_17_1To1_17;
|
||||
import com.viaversion.viabackwards.protocol.v1_19to1_18_2.Protocol1_19To1_18_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_17to1_16_4.Protocol1_17To1_16_4;
|
||||
import com.viaversion.viabackwards.protocol.v1_18_2to1_18.Protocol1_18_2To1_18;
|
||||
import com.viaversion.viabackwards.protocol.v1_18to1_17_1.Protocol1_18To1_17_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_19_1to1_19.Protocol1_19_1To1_19;
|
||||
import com.viaversion.viabackwards.protocol.v1_19_3to1_19_1.Protocol1_19_3To1_19_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_19_4to1_19_3.Protocol1_19_4To1_19_3;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_4to1_21_2.Protocol1_21_4To1_21_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_20to1_19_4.Protocol1_20To1_19_4;
|
||||
import com.viaversion.viabackwards.protocol.v1_19_1to1_19.Protocol1_19_1To1_19;
|
||||
import com.viaversion.viabackwards.protocol.v1_19to1_18_2.Protocol1_19To1_18_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_20_2to1_20.Protocol1_20_2To1_20;
|
||||
import com.viaversion.viabackwards.protocol.v1_20_3to1_20_2.Protocol1_20_3To1_20_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_20_5to1_20_3.Protocol1_20_5To1_20_3;
|
||||
import com.viaversion.viabackwards.protocol.v1_20_2to1_20.Protocol1_20_2To1_20;
|
||||
import com.viaversion.viabackwards.protocol.v1_20to1_19_4.Protocol1_20To1_19_4;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.task.PlayerPacketsTickTask;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_4to1_21_2.Protocol1_21_4To1_21_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_5to1_21_4.Protocol1_21_5To1_21_4;
|
||||
import com.viaversion.viabackwards.protocol.v1_21to1_20_5.Protocol1_21To1_20_5;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.Protocol1_21_6To1_21_5;
|
||||
import com.viaversion.viabackwards.protocol.v1_9_3to1_9_1.Protocol1_9_3To1_9_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_10to1_9_3.Protocol1_10To1_9_3;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.task.ChestDialogViewTask;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_7to1_21_6.Protocol1_21_7To1_21_6;
|
||||
import com.viaversion.viabackwards.protocol.v1_21to1_20_5.Protocol1_21To1_20_5;
|
||||
import com.viaversion.viabackwards.protocol.v1_9_1to1_9.Protocol1_9_1To1_9;
|
||||
import com.viaversion.viabackwards.protocol.v1_9_3to1_9_1.Protocol1_9_3To1_9_1;
|
||||
import com.viaversion.viabackwards.utils.VersionInfo;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.protocol.ProtocolManager;
|
||||
@@ -151,6 +153,7 @@ public interface ViaBackwardsPlatform {
|
||||
protocolManager.registerProtocol(new Protocol1_21_5To1_21_4(), ProtocolVersion.v1_21_4, ProtocolVersion.v1_21_5);
|
||||
|
||||
protocolManager.registerProtocol(new Protocol1_21_6To1_21_5(), ProtocolVersion.v1_21_5, ProtocolVersion.v1_21_6);
|
||||
protocolManager.registerProtocol(new Protocol1_21_7To1_21_6(), ProtocolVersion.v1_21_6, ProtocolVersion.v1_21_7);
|
||||
}
|
||||
|
||||
default void enable() {
|
||||
@@ -158,6 +161,10 @@ public interface ViaBackwardsPlatform {
|
||||
if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_21_2)) {
|
||||
Via.getPlatform().runRepeatingSync(new PlayerPacketsTickTask(), 1L);
|
||||
}
|
||||
|
||||
if (protocolVersion.newerThanOrEqualTo(ProtocolVersion.v1_21_6)) {
|
||||
Via.getPlatform().runRepeatingSync(new ChestDialogViewTask(), 20L);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
package com.viaversion.viabackwards.api.data;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.NumberTag;
|
||||
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.viaversion.api.Via;
|
||||
@@ -30,10 +34,6 @@ import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectArrayMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.NumberTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
+2
-2
@@ -17,10 +17,10 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.api.data;
|
||||
|
||||
import com.viaversion.viabackwards.ViaBackwards;
|
||||
import com.viaversion.viaversion.api.data.MappingDataLoader;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.ViaBackwards;
|
||||
import com.viaversion.viaversion.api.data.MappingDataLoader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
+1
-1
@@ -18,9 +18,9 @@
|
||||
|
||||
package com.viaversion.viabackwards.api.entities.storage;
|
||||
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.util.ComponentUtil;
|
||||
import java.util.Locale;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
+36
-17
@@ -26,11 +26,14 @@ import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viabackwards.api.data.MappedItem;
|
||||
import com.viaversion.viabackwards.item.DataItemWithExtras;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class BackwardsItemRewriter<C extends ClientboundPacketType, S extends ServerboundPacketType,
|
||||
@@ -52,29 +55,45 @@ public class BackwardsItemRewriter<C extends ClientboundPacketType, S extends Se
|
||||
|
||||
CompoundTag display = item.tag() != null ? item.tag().getCompoundTag("display") : null;
|
||||
if (protocol.getComponentRewriter() != null && display != null) {
|
||||
// Handle name and lore components
|
||||
StringTag name = display.getStringTag("Name");
|
||||
if (name != null) {
|
||||
String newValue = protocol.getComponentRewriter().processText(connection, name.getValue()).toString();
|
||||
if (!newValue.equals(name.getValue())) {
|
||||
saveStringTag(display, name, "Name");
|
||||
}
|
||||
|
||||
name.setValue(newValue);
|
||||
final DataItemWithExtras fullItem;
|
||||
if (item instanceof DataItemWithExtras) {
|
||||
fullItem = (DataItemWithExtras) item;
|
||||
} else {
|
||||
item = fullItem = new DataItemWithExtras(item);
|
||||
}
|
||||
|
||||
ListTag<StringTag> lore = display.getListTag("Lore", StringTag.class);
|
||||
// Handle name and lore components
|
||||
final JsonElement name = fullItem.name();
|
||||
if (name != null) {
|
||||
final JsonElement updatedName = name.deepCopy();
|
||||
protocol.getComponentRewriter().processText(connection, updatedName);
|
||||
if (!updatedName.equals(name)) {
|
||||
final StringTag rawName = fullItem.rawName();
|
||||
saveStringTag(display, rawName, "Name");
|
||||
rawName.setValue(updatedName.toString());
|
||||
}
|
||||
}
|
||||
|
||||
final List<JsonElement> lore = fullItem.lore();
|
||||
if (lore != null) {
|
||||
boolean changed = false;
|
||||
for (StringTag loreEntry : lore) {
|
||||
String newValue = protocol.getComponentRewriter().processText(connection, loreEntry.getValue()).toString();
|
||||
if (!changed && !newValue.equals(loreEntry.getValue())) {
|
||||
// Backup original lore before doing any modifications
|
||||
changed = true;
|
||||
saveListTag(display, lore, "Lore");
|
||||
final ListTag<StringTag> rawLore = fullItem.rawLore();
|
||||
for (int i = 0; i < lore.size(); i++) {
|
||||
final JsonElement loreEntry = lore.get(i);
|
||||
final JsonElement updatedLoreEntry = loreEntry.deepCopy();
|
||||
protocol.getComponentRewriter().processText(connection, updatedLoreEntry);
|
||||
if (updatedLoreEntry.equals(loreEntry)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
loreEntry.setValue(newValue);
|
||||
if (!changed) {
|
||||
// Backup original lore before doing any modifications
|
||||
changed = true;
|
||||
saveListTag(display, rawLore, "Lore");
|
||||
}
|
||||
|
||||
final StringTag rawLoreEntry = rawLore.get(i);
|
||||
rawLoreEntry.setValue(updatedLoreEntry.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-6
@@ -17,19 +17,17 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.api.rewriters;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
||||
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.rewriter.ItemRewriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public abstract class BackwardsItemRewriterBase<C extends ClientboundPacketType, S extends ServerboundPacketType,
|
||||
|
||||
+2
-2
@@ -17,12 +17,12 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.api.rewriters;
|
||||
|
||||
import com.viaversion.viabackwards.utils.ChatUtil;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.NumberTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viabackwards.utils.ChatUtil;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
+1
-1
@@ -175,7 +175,7 @@ public abstract class EntityRewriterBase<C extends ClientboundPacketType, T exte
|
||||
filter().handler((event, data) -> {
|
||||
EntityDataType type = data.dataType();
|
||||
if (type == itemType) {
|
||||
protocol.getItemRewriter().handleItemToClient(event.user(), data.value());
|
||||
data.setValue(protocol.getItemRewriter().handleItemToClient(event.user(), data.value()));
|
||||
} else if (type == blockStateType) {
|
||||
int value = data.value();
|
||||
data.setValue(protocol.getMappingData().getNewBlockStateId(value));
|
||||
|
||||
+1
-1
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.api.rewriters;
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.nbt.tag.ByteTag;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.IntTag;
|
||||
@@ -25,6 +24,7 @@ import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.NumberTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
@@ -64,12 +64,11 @@ public class SoundRewriter<C extends ClientboundPacketType> extends com.viaversi
|
||||
public PacketHandler getStopSoundHandler() {
|
||||
return wrapper -> {
|
||||
final byte flags = wrapper.passthrough(Types.BYTE);
|
||||
if ((flags & 0x02) == 0) return; // No sound specified
|
||||
|
||||
if ((flags & 0x01) != 0) {
|
||||
wrapper.passthrough(Types.VAR_INT); // Source
|
||||
}
|
||||
|
||||
if ((flags & 0x02) == 0) return; // No sound specified
|
||||
final String soundId = wrapper.read(Types.STRING);
|
||||
final String mappedId = protocol.getMappingData().getMappedNamedSound(soundId);
|
||||
if (mappedId == null) {
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.item;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.api.minecraft.item.DataItem;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.viaversion.libs.gson.JsonParser;
|
||||
import com.viaversion.viaversion.libs.gson.JsonPrimitive;
|
||||
import com.viaversion.viaversion.libs.gson.JsonSyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Prevent expensive parsing/toString by checking against cached JsonElement instances, used from 1.14 to 1.20.5.
|
||||
* <p>
|
||||
* When using this, be careful not to break caching by modifying the display tag directly.
|
||||
*/
|
||||
public final class DataItemWithExtras extends DataItem {
|
||||
|
||||
private JsonElement name;
|
||||
private List<JsonElement> lore;
|
||||
|
||||
public DataItemWithExtras(final Item from) {
|
||||
setIdentifier(from.identifier());
|
||||
setAmount(from.amount());
|
||||
setData(from.data());
|
||||
setTag(from.tag());
|
||||
|
||||
if (tag() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final CompoundTag display = tag().getCompoundTag("display");
|
||||
if (display == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final StringTag name = display.getStringTag("Name");
|
||||
if (name != null) {
|
||||
this.name = parse(name.getValue());
|
||||
}
|
||||
|
||||
final ListTag<StringTag> lore = display.getListTag("Lore", StringTag.class);
|
||||
if (lore != null) {
|
||||
this.lore = new ArrayList<>(lore.size());
|
||||
for (int i = 0; i < lore.size(); i++) {
|
||||
this.lore.add(parse(lore.get(i).getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable JsonElement name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public @Nullable StringTag rawName() {
|
||||
if (tag() == null) {
|
||||
return null;
|
||||
}
|
||||
final CompoundTag display = tag().getCompoundTag("display");
|
||||
return display != null ? display.getStringTag("Name") : null;
|
||||
}
|
||||
|
||||
public @Nullable List<JsonElement> lore() {
|
||||
return lore;
|
||||
}
|
||||
|
||||
public @Nullable ListTag<StringTag> rawLore() {
|
||||
if (tag() == null) {
|
||||
return null;
|
||||
}
|
||||
final CompoundTag display = tag().getCompoundTag("display");
|
||||
return display != null ? display.getListTag("Lore", StringTag.class) : null;
|
||||
}
|
||||
|
||||
private JsonElement parse(final String value) {
|
||||
try {
|
||||
return JsonParser.parseString(value);
|
||||
} catch (final JsonSyntaxException e) {
|
||||
return new JsonPrimitive(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -157,6 +157,9 @@ public class EntityPacketRewriter1_10 extends LegacyEntityRewriter<ClientboundPa
|
||||
}
|
||||
});
|
||||
|
||||
// Added index from incorrect entity data hierarchy, where potions add to item entities
|
||||
filter().type(EntityTypes1_10.EntityType.POTION).addIndex(6);
|
||||
|
||||
// Handle the missing NoGravity tag for every entity data
|
||||
filter().removeIndex(5);
|
||||
}
|
||||
|
||||
-2
@@ -23,8 +23,6 @@ import com.viaversion.viabackwards.api.rewriters.LegacyEnchantmentRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_11_1to1_11.Protocol1_11_1To1_11;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.packet.ClientboundPackets1_9_3;
|
||||
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.packet.ServerboundPackets1_9_3;
|
||||
|
||||
+2
-2
@@ -18,6 +18,8 @@
|
||||
|
||||
package com.viaversion.viabackwards.protocol.v1_11to1_10.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viabackwards.api.data.MappedLegacyBlockItem;
|
||||
import com.viaversion.viabackwards.api.rewriters.LegacyBlockItemRewriter;
|
||||
import com.viaversion.viabackwards.api.rewriters.LegacyEnchantmentRewriter;
|
||||
@@ -35,8 +37,6 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_9_3;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.protocols.v1_10to1_11.data.EntityMappings1_11;
|
||||
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.packet.ClientboundPackets1_9_3;
|
||||
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.packet.ServerboundPackets1_9_3;
|
||||
|
||||
+1
-1
@@ -20,11 +20,11 @@ package com.viaversion.viabackwards.protocol.v1_12to1_11_1;
|
||||
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
|
||||
import com.viaversion.viabackwards.protocol.v1_12to1_11_1.storage.ShoulderTracker;
|
||||
import com.viaversion.viabackwards.protocol.v1_12to1_11_1.rewriter.BlockItemPacketRewriter1_12;
|
||||
import com.viaversion.viabackwards.protocol.v1_12to1_11_1.rewriter.ComponentRewriter1_12;
|
||||
import com.viaversion.viabackwards.protocol.v1_12to1_11_1.rewriter.EntityPacketRewriter1_12;
|
||||
import com.viaversion.viabackwards.protocol.v1_12to1_11_1.rewriter.SoundPacketRewriter1_12;
|
||||
import com.viaversion.viabackwards.protocol.v1_12to1_11_1.storage.ShoulderTracker;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.ClientWorld;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_12;
|
||||
|
||||
+6
-6
@@ -18,7 +18,11 @@
|
||||
|
||||
package com.viaversion.viabackwards.protocol.v1_12to1_11_1.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.IntArrayTag;
|
||||
import com.viaversion.nbt.tag.LongArrayTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.api.rewriters.LegacyBlockItemRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_12to1_11_1.Protocol1_12To1_11_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_12to1_11_1.data.MapColorMappings1_11_1;
|
||||
@@ -30,18 +34,14 @@ import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_9_3;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.IntArrayTag;
|
||||
import com.viaversion.nbt.tag.LongArrayTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.protocols.v1_11_1to1_12.packet.ClientboundPackets1_12;
|
||||
import com.viaversion.viaversion.protocols.v1_11_1to1_12.packet.ServerboundPackets1_12;
|
||||
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.packet.ServerboundPackets1_9_3;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import com.viaversion.viaversion.util.ComponentUtil;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.SerializerVersion;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class BlockItemPacketRewriter1_12 extends LegacyBlockItemRewriter<ClientboundPackets1_12, ServerboundPackets1_9_3, Protocol1_12To1_11_1> {
|
||||
|
||||
-1
@@ -21,7 +21,6 @@ package com.viaversion.viabackwards.protocol.v1_12to1_11_1.rewriter;
|
||||
import com.viaversion.viabackwards.api.rewriters.LegacySoundRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_12to1_11_1.Protocol1_12To1_11_1;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_11_1to1_12.packet.ClientboundPackets1_12;
|
||||
|
||||
|
||||
+1
-1
@@ -40,10 +40,10 @@ import com.viaversion.viaversion.libs.gson.JsonObject;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ServerboundPackets1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_13to1_13_1.Protocol1_13To1_13_1;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.util.ComponentUtil;
|
||||
|
||||
public class Protocol1_13_1To1_13 extends BackwardsProtocol<ClientboundPackets1_13, ClientboundPackets1_13, ServerboundPackets1_13, ServerboundPackets1_13> {
|
||||
|
||||
+1
-1
@@ -131,7 +131,7 @@ public class EntityPacketRewriter1_13_1 extends LegacyEntityRewriter<Clientbound
|
||||
// Rewrite items & blocks
|
||||
filter().handler((event, data) -> {
|
||||
if (data.dataType() == Types1_13.ENTITY_DATA_TYPES.itemType) {
|
||||
protocol.getItemRewriter().handleItemToClient(event.user(), (Item) data.getValue());
|
||||
data.setValue(protocol.getItemRewriter().handleItemToClient(event.user(), (Item) data.getValue()));
|
||||
} else if (data.dataType() == Types1_13.ENTITY_DATA_TYPES.optionalBlockStateType) {
|
||||
// Convert to new block id
|
||||
int value = (int) data.getValue();
|
||||
|
||||
+1
-1
@@ -19,8 +19,8 @@ package com.viaversion.viabackwards.protocol.v1_13_1to1_13.rewriter;
|
||||
|
||||
import com.viaversion.viabackwards.protocol.v1_13_1to1_13.Protocol1_13_1To1_13;
|
||||
import com.viaversion.viaversion.api.minecraft.BlockFace;
|
||||
import com.viaversion.viaversion.api.minecraft.ClientWorld;
|
||||
import com.viaversion.viaversion.api.minecraft.BlockPosition;
|
||||
import com.viaversion.viaversion.api.minecraft.ClientWorld;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
|
||||
-1
@@ -23,7 +23,6 @@ import com.viaversion.viabackwards.protocol.v1_13_2to1_13_1.rewriter.ItemPacketR
|
||||
import com.viaversion.viabackwards.protocol.v1_13_2to1_13_1.rewriter.WorldPacketRewriter1_13_2;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ServerboundPackets1_13;
|
||||
|
||||
-1
@@ -19,7 +19,6 @@ package com.viaversion.viabackwards.protocol.v1_13_2to1_13_1.rewriter;
|
||||
|
||||
import com.viaversion.viabackwards.protocol.v1_13_2to1_13_1.Protocol1_13_2To1_13_1;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ServerboundPackets1_13;
|
||||
|
||||
-1
@@ -19,7 +19,6 @@ package com.viaversion.viabackwards.protocol.v1_13_2to1_13_1.rewriter;
|
||||
|
||||
import com.viaversion.viabackwards.protocol.v1_13_2to1_13_1.Protocol1_13_2To1_13_1;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
|
||||
|
||||
|
||||
+1
-1
@@ -40,11 +40,11 @@ import com.viaversion.viaversion.data.entity.EntityTrackerBase;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.viaversion.libs.gson.JsonObject;
|
||||
import com.viaversion.viaversion.libs.gson.JsonParser;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.Protocol1_12_2To1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ServerboundPackets1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12to1_12_1.packet.ClientboundPackets1_12_1;
|
||||
import com.viaversion.viaversion.protocols.v1_12to1_12_1.packet.ServerboundPackets1_12_1;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.Protocol1_12_2To1_13;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.util.ComponentUtil;
|
||||
import com.viaversion.viaversion.util.ProtocolLogger;
|
||||
|
||||
+2
-2
@@ -18,11 +18,11 @@
|
||||
|
||||
package com.viaversion.viabackwards.protocol.v1_13to1_12_2.block_entity_handlers;
|
||||
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.Protocol1_13To1_12_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.provider.BackwardsBlockEntityProvider.BackwardsBlockEntityHandler;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.NumberTag;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.Protocol1_13To1_12_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.provider.BackwardsBlockEntityProvider.BackwardsBlockEntityHandler;
|
||||
|
||||
public class BannerHandler implements BackwardsBlockEntityHandler {
|
||||
private static final int WALL_BANNER_START = 7110; // 4 each
|
||||
|
||||
+1
-1
@@ -18,8 +18,8 @@
|
||||
|
||||
package com.viaversion.viabackwards.protocol.v1_13to1_12_2.block_entity_handlers;
|
||||
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.provider.BackwardsBlockEntityProvider;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.provider.BackwardsBlockEntityProvider;
|
||||
|
||||
public class BedHandler implements BackwardsBlockEntityProvider.BackwardsBlockEntityHandler {
|
||||
|
||||
|
||||
+1
-1
@@ -18,10 +18,10 @@
|
||||
|
||||
package com.viaversion.viabackwards.protocol.v1_13to1_12_2.block_entity_handlers;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.provider.BackwardsBlockEntityProvider;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.util.Pair;
|
||||
|
||||
public class FlowerPotHandler implements BackwardsBlockEntityProvider.BackwardsBlockEntityHandler {
|
||||
|
||||
+4
-4
@@ -17,16 +17,16 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_13to1_12_2.block_entity_handlers;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.Protocol1_13To1_12_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.provider.BackwardsBlockEntityProvider;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.data.MappingDataLoader;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntOpenHashMap;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.blockconnections.ConnectionData;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
+1
-1
@@ -18,8 +18,8 @@
|
||||
|
||||
package com.viaversion.viabackwards.protocol.v1_13to1_12_2.block_entity_handlers;
|
||||
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.provider.BackwardsBlockEntityProvider.BackwardsBlockEntityHandler;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.provider.BackwardsBlockEntityProvider.BackwardsBlockEntityHandler;
|
||||
|
||||
public class SkullHandler implements BackwardsBlockEntityHandler {
|
||||
private static final int SKULL_START = 5447;
|
||||
|
||||
+2
-2
@@ -18,10 +18,10 @@
|
||||
|
||||
package com.viaversion.viabackwards.protocol.v1_13to1_12_2.block_entity_handlers;
|
||||
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.data.EntityNameMappings1_12_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.provider.BackwardsBlockEntityProvider;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.data.EntityNameMappings1_12_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.provider.BackwardsBlockEntityProvider;
|
||||
|
||||
public class SpawnerHandler implements BackwardsBlockEntityProvider.BackwardsBlockEntityHandler {
|
||||
|
||||
|
||||
+1
-1
@@ -18,10 +18,10 @@
|
||||
|
||||
package com.viaversion.viabackwards.protocol.v1_13to1_12_2.data;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.Protocol1_12_2To1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.data.StatisticMappings1_13;
|
||||
import java.util.HashMap;
|
||||
|
||||
+2
-2
@@ -18,6 +18,8 @@
|
||||
|
||||
package com.viaversion.viabackwards.protocol.v1_13to1_12_2.provider;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.block_entity_handlers.BannerHandler;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.block_entity_handlers.BedHandler;
|
||||
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.block_entity_handlers.FlowerPotHandler;
|
||||
@@ -28,8 +30,6 @@ import com.viaversion.viabackwards.protocol.v1_13to1_12_2.storage.BackwardsBlock
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.BlockPosition;
|
||||
import com.viaversion.viaversion.api.platform.providers.Provider;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
+10
-10
@@ -19,6 +19,13 @@
|
||||
package com.viaversion.viabackwards.protocol.v1_13to1_12_2.rewriter;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
import com.viaversion.nbt.tag.ByteTag;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.IntTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.NumberTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.ViaBackwards;
|
||||
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
|
||||
import com.viaversion.viabackwards.api.rewriters.EnchantmentRewriter;
|
||||
@@ -30,8 +37,8 @@ import com.viaversion.viabackwards.protocol.v1_13to1_12_2.storage.NoteBlockStora
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
|
||||
import com.viaversion.viaversion.api.minecraft.ClientWorld;
|
||||
import com.viaversion.viaversion.api.minecraft.BlockPosition;
|
||||
import com.viaversion.viaversion.api.minecraft.ClientWorld;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
|
||||
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
|
||||
@@ -42,19 +49,12 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_13;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_9_3;
|
||||
import com.viaversion.nbt.tag.ByteTag;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.IntTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.NumberTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.Protocol1_12_2To1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.data.BlockIdData;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.data.SpawnEggMappings1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12to1_12_1.packet.ClientboundPackets1_12_1;
|
||||
import com.viaversion.viaversion.protocols.v1_12to1_12_1.packet.ServerboundPackets1_12_1;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.Protocol1_12_2To1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.data.BlockIdData;
|
||||
import com.viaversion.viaversion.util.ComponentUtil;
|
||||
import com.viaversion.viaversion.util.IdAndData;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
|
||||
+2
-2
@@ -34,11 +34,11 @@ import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
|
||||
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ServerboundPackets1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.rewriter.ItemPacketRewriter1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12to1_12_1.packet.ClientboundPackets1_12_1;
|
||||
import com.viaversion.viaversion.protocols.v1_12to1_12_1.packet.ServerboundPackets1_12_1;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
|
||||
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ServerboundPackets1_13;
|
||||
import com.viaversion.viaversion.rewriter.CommandRewriter;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
-1
@@ -18,7 +18,6 @@
|
||||
package com.viaversion.viabackwards.protocol.v1_14_3to1_14_2;
|
||||
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ClientboundPackets1_14;
|
||||
import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ServerboundPackets1_14;
|
||||
|
||||
-1
@@ -19,7 +19,6 @@ package com.viaversion.viabackwards.protocol.v1_14_4to1_14_3;
|
||||
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ClientboundPackets1_14;
|
||||
import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ServerboundPackets1_14;
|
||||
|
||||
+25
-21
@@ -24,6 +24,7 @@ import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viabackwards.api.data.TranslatableMappings;
|
||||
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
|
||||
import com.viaversion.viabackwards.api.rewriters.EnchantmentRewriter;
|
||||
import com.viaversion.viabackwards.item.DataItemWithExtras;
|
||||
import com.viaversion.viabackwards.protocol.v1_14to1_13_2.Protocol1_14To1_13_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_14to1_13_2.storage.ChunkLightStorage;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
@@ -39,6 +40,7 @@ import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_14;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
|
||||
import com.viaversion.viaversion.api.minecraft.item.DataItem;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
@@ -61,7 +63,6 @@ import com.viaversion.viaversion.util.ComponentUtil;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.SerializerVersion;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -462,31 +463,34 @@ public class BlockItemPacketRewriter1_14 extends BackwardsItemRewriter<Clientbou
|
||||
super.handleItemToClient(connection, item);
|
||||
|
||||
// Lore now uses JSON
|
||||
CompoundTag tag = item.tag();
|
||||
CompoundTag display;
|
||||
if (tag != null && (display = tag.getCompoundTag("display")) != null) {
|
||||
ListTag<StringTag> lore = display.getListTag("Lore", StringTag.class);
|
||||
if (lore != null) {
|
||||
saveListTag(display, lore, "Lore");
|
||||
final CompoundTag display = item.tag() != null ? item.tag().getCompoundTag("display") : null;
|
||||
if (display != null && item instanceof DataItemWithExtras fullItem && fullItem.lore() != null) {
|
||||
final List<JsonElement> lore = fullItem.lore();
|
||||
final ListTag<StringTag> loreTag = fullItem.rawLore();
|
||||
saveListTag(display, loreTag, "Lore");
|
||||
|
||||
try {
|
||||
final Iterator<StringTag> each = lore.iterator();
|
||||
while (each.hasNext()) {
|
||||
final StringTag loreEntry = each.next();
|
||||
final var component = SerializerVersion.V1_12.toComponent(loreEntry.getValue());
|
||||
if (component == null) {
|
||||
each.remove();
|
||||
continue;
|
||||
}
|
||||
TextUtils.setTranslator(component, s -> Protocol1_12_2To1_13.MAPPINGS.getMojangTranslation().
|
||||
getOrDefault(s, TranslatableMappings.getTranslatableMappings("1.14").get(s)));
|
||||
loreEntry.setValue(component.asLegacyFormatString());
|
||||
try {
|
||||
for (int i = 0; i < lore.size(); i++) {
|
||||
final JsonElement loreEntry = lore.get(i);
|
||||
final var component = SerializerVersion.V1_12.toComponent(loreEntry);
|
||||
if (component == null) {
|
||||
lore.remove(i);
|
||||
loreTag.remove(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
} catch (final JsonParseException e) {
|
||||
display.remove("Lore");
|
||||
|
||||
TextUtils.setTranslator(component, s -> Protocol1_12_2To1_13.MAPPINGS.getMojangTranslation()
|
||||
.getOrDefault(s, TranslatableMappings.getTranslatableMappings("1.14").get(s)));
|
||||
loreTag.get(i).setValue(component.asLegacyFormatString());
|
||||
}
|
||||
} catch (final JsonParseException e) {
|
||||
display.remove("Lore");
|
||||
}
|
||||
}
|
||||
if (item instanceof DataItemWithExtras) {
|
||||
item = new DataItem(item.identifier(), (byte) item.amount(), item.data(), item.tag()); // back to a normal DataItem
|
||||
}
|
||||
|
||||
enchantmentRewriter.handleToClient(item);
|
||||
return item;
|
||||
|
||||
-1
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_14to1_13_2.rewriter;
|
||||
|
||||
import com.viaversion.viabackwards.ViaBackwards;
|
||||
import com.viaversion.viabackwards.api.rewriters.SoundRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_14to1_13_2.Protocol1_14To1_13_2;
|
||||
import com.viaversion.viabackwards.protocol.v1_14to1_13_2.storage.EntityPositionStorage1_14;
|
||||
|
||||
+1
-1
@@ -36,10 +36,10 @@ import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ServerboundPacke
|
||||
import com.viaversion.viaversion.protocols.v1_14_3to1_14_4.packet.ClientboundPackets1_14_4;
|
||||
import com.viaversion.viaversion.protocols.v1_14_4to1_15.Protocol1_14_4To1_15;
|
||||
import com.viaversion.viaversion.protocols.v1_14_4to1_15.packet.ClientboundPackets1_15;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
|
||||
public class Protocol1_15To1_14_4 extends BackwardsProtocol<ClientboundPackets1_15, ClientboundPackets1_14_4, ServerboundPackets1_14, ServerboundPackets1_14> {
|
||||
|
||||
|
||||
+1
-1
@@ -37,10 +37,10 @@ import com.viaversion.viaversion.protocols.v1_15_2to1_16.packet.ServerboundPacke
|
||||
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.Protocol1_16_1To1_16_2;
|
||||
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ClientboundPackets1_16_2;
|
||||
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ServerboundPackets1_16_2;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.util.ProtocolLogger;
|
||||
|
||||
public class Protocol1_16_2To1_16_1 extends BackwardsProtocol<ClientboundPackets1_16_2, ClientboundPackets1_16, ServerboundPackets1_16_2, ServerboundPackets1_16> {
|
||||
|
||||
-1
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.data;
|
||||
|
||||
import com.viaversion.viabackwards.ViaBackwards;
|
||||
import com.viaversion.viabackwards.api.data.BackwardsMappingDataLoader;
|
||||
import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.Protocol1_16_2To1_16_1;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
|
||||
-1
@@ -21,7 +21,6 @@ import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viabackwards.protocol.v1_16_4to1_16_3.storage.PlayerHandStorage;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ClientboundPackets1_16_2;
|
||||
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ServerboundPackets1_16_2;
|
||||
|
||||
+7
-9
@@ -17,18 +17,16 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_17_1to1_17;
|
||||
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viabackwards.protocol.v1_17to1_16_4.storage.PlayerLastCursorItem;
|
||||
import com.viaversion.viabackwards.protocol.v1_17_1to1_17.storage.InventoryStateIds;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Type;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viabackwards.protocol.v1_17_1to1_17.storage.InventoryStateIds;
|
||||
import com.viaversion.viabackwards.protocol.v1_17to1_16_4.storage.PlayerLastCursorItem;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ClientboundPackets1_17;
|
||||
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPackets1_17;
|
||||
import com.viaversion.viaversion.protocols.v1_17to1_17_1.packet.ClientboundPackets1_17_1;
|
||||
|
||||
+1
-1
@@ -40,11 +40,11 @@ import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ServerboundPac
|
||||
import com.viaversion.viaversion.protocols.v1_16_4to1_17.Protocol1_16_4To1_17;
|
||||
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ClientboundPackets1_17;
|
||||
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPackets1_17;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.rewriter.IdRewriteFunction;
|
||||
import com.viaversion.viaversion.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
+3
-4
@@ -17,7 +17,9 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_18_2to1_18;
|
||||
|
||||
import com.viaversion.viabackwards.ViaBackwards;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viabackwards.protocol.v1_18_2to1_18.rewriter.CommandRewriter1_18_2;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
@@ -25,9 +27,6 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPackets1_17;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.protocols.v1_17_1to1_18.packet.ClientboundPackets1_18;
|
||||
import com.viaversion.viaversion.util.TagUtil;
|
||||
|
||||
|
||||
+1
-1
@@ -33,9 +33,9 @@ import com.viaversion.viaversion.data.entity.EntityTrackerBase;
|
||||
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPackets1_17;
|
||||
import com.viaversion.viaversion.protocols.v1_17_1to1_18.packet.ClientboundPackets1_18;
|
||||
import com.viaversion.viaversion.protocols.v1_17to1_17_1.packet.ClientboundPackets1_17_1;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
|
||||
public final class Protocol1_18To1_17_1 extends BackwardsProtocol<ClientboundPackets1_18, ClientboundPackets1_17_1, ServerboundPackets1_17, ServerboundPackets1_17> {
|
||||
|
||||
|
||||
+1
-1
@@ -17,11 +17,11 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_18to1_17_1.data;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntMap;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.protocols.v1_17_1to1_18.Protocol1_17_1To1_18;
|
||||
import com.viaversion.viaversion.protocols.v1_17_1to1_18.data.BlockEntities1_18;
|
||||
|
||||
|
||||
+1
-1
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_18to1_17_1.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viabackwards.api.rewriters.BackwardsItemRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_18to1_17_1.Protocol1_18To1_17_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_18to1_17_1.data.BlockEntityMappings1_17_1;
|
||||
@@ -35,7 +36,6 @@ import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_17;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_18;
|
||||
import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPackets1_17;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.protocols.v1_17_1to1_18.packet.ClientboundPackets1_18;
|
||||
import com.viaversion.viaversion.protocols.v1_17to1_17_1.packet.ClientboundPackets1_17_1;
|
||||
import com.viaversion.viaversion.rewriter.RecipeRewriter;
|
||||
|
||||
+4
-4
@@ -17,6 +17,9 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_19_1to1_19;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.NumberTag;
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viabackwards.api.rewriters.text.JsonNBTComponentRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_19_1to1_19.rewriter.EntityPacketRewriter1_19_1;
|
||||
@@ -40,17 +43,14 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.NumberTag;
|
||||
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
|
||||
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
|
||||
import com.viaversion.viaversion.protocols.v1_18_2to1_19.Protocol1_18_2To1_19;
|
||||
import com.viaversion.viaversion.protocols.v1_18_2to1_19.packet.ClientboundPackets1_19;
|
||||
import com.viaversion.viaversion.protocols.v1_18_2to1_19.packet.ServerboundPackets1_19;
|
||||
import com.viaversion.viaversion.protocols.v1_19to1_19_1.Protocol1_19To1_19_1;
|
||||
import com.viaversion.viaversion.protocols.v1_19to1_19_1.packet.ClientboundPackets1_19_1;
|
||||
import com.viaversion.viaversion.protocols.v1_19to1_19_1.packet.ServerboundPackets1_19_1;
|
||||
import com.viaversion.viaversion.protocols.v1_18_2to1_19.Protocol1_18_2To1_19;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.util.CipherUtil;
|
||||
import com.viaversion.viaversion.util.ComponentUtil;
|
||||
|
||||
+1
-6
@@ -17,10 +17,10 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_19_1to1_19.storage;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.protocols.v1_18_2to1_19.Protocol1_18_2To1_19;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
@@ -39,9 +39,4 @@ public abstract class ChatRegistryStorage implements StorableObject {
|
||||
public void clear() {
|
||||
chatTypes.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearOnServerSwitch() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -54,10 +54,10 @@ import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.packet.ServerboundPac
|
||||
import com.viaversion.viaversion.protocols.v1_19to1_19_1.packet.ClientboundPackets1_19_1;
|
||||
import com.viaversion.viaversion.protocols.v1_19to1_19_1.packet.ServerboundPackets1_19_1;
|
||||
import com.viaversion.viaversion.rewriter.CommandRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.util.CipherUtil;
|
||||
import com.viaversion.viaversion.util.ComponentUtil;
|
||||
import com.viaversion.viaversion.util.Pair;
|
||||
|
||||
+1
-1
@@ -17,13 +17,13 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_19_3to1_19_1.data;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
|
||||
import com.viaversion.viabackwards.api.data.BackwardsMappingDataLoader;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntOpenHashMap;
|
||||
import com.viaversion.viaversion.libs.gson.JsonArray;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.Protocol1_19_1To1_19_3;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
|
||||
|
||||
+3
-3
@@ -17,6 +17,9 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_19_3to1_19_1.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.NumberTag;
|
||||
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_19_3to1_19_1.Protocol1_19_3To1_19_1;
|
||||
import com.viaversion.viabackwards.protocol.v1_19_3to1_19_1.storage.ChatTypeStorage1_19_3;
|
||||
@@ -31,9 +34,6 @@ import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_19;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_19_3;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.NumberTag;
|
||||
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.packet.ClientboundPackets1_19_3;
|
||||
import com.viaversion.viaversion.protocols.v1_19_1to1_19_3.packet.ServerboundPackets1_19_3;
|
||||
import com.viaversion.viaversion.protocols.v1_19to1_19_1.packet.ClientboundPackets1_19_1;
|
||||
|
||||
+1
-1
@@ -34,10 +34,10 @@ import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.Protocol1_19_3To1_19_
|
||||
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ClientboundPackets1_19_4;
|
||||
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ServerboundPackets1_19_4;
|
||||
import com.viaversion.viaversion.rewriter.CommandRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
|
||||
+1
-1
@@ -268,7 +268,7 @@ public final class EntityPacketRewriter1_19_4 extends EntityRewriter<Clientbound
|
||||
|
||||
final PacketWrapper wrapper = PacketWrapper.create(ClientboundPackets1_19_3.SET_PASSENGERS, event.user());
|
||||
wrapper.write(Types.VAR_INT, event.entityId()); // Entity id
|
||||
wrapper.write(Types.VAR_INT_ARRAY_PRIMITIVE, new int[] { linkedEntity }); // Passenger entity ids
|
||||
wrapper.write(Types.VAR_INT_ARRAY_PRIMITIVE, new int[]{linkedEntity}); // Passenger entity ids
|
||||
wrapper.send(Protocol1_19_4To1_19_3.class);
|
||||
});
|
||||
filter().type(EntityTypes1_19_4.ITEM_DISPLAY).index(22).handler((event, data) -> {
|
||||
|
||||
+1
-1
@@ -50,10 +50,10 @@ import com.viaversion.viaversion.protocols.v1_18_2to1_19.packet.ServerboundPacke
|
||||
import com.viaversion.viaversion.protocols.v1_19to1_19_1.Protocol1_19To1_19_1;
|
||||
import com.viaversion.viaversion.protocols.v1_19to1_19_1.data.ChatDecorationResult;
|
||||
import com.viaversion.viaversion.rewriter.CommandRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.util.Pair;
|
||||
import java.security.SignatureException;
|
||||
import java.time.Instant;
|
||||
|
||||
+1
-1
@@ -190,7 +190,7 @@ public final class EntityPacketRewriter1_19 extends EntityRewriter<ClientboundPa
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
throw new IllegalStateException("Could not find dimension " + dimensionKey + " in dimension registry");
|
||||
throw new IllegalArgumentException("Could not find dimension " + dimensionKey + " in dimension registry");
|
||||
}
|
||||
|
||||
// Add biome category and track biomes
|
||||
|
||||
+2
-7
@@ -17,14 +17,14 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_19to1_18_2.storage;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viabackwards.protocol.v1_19to1_18_2.Protocol1_19To1_18_2;
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class DimensionRegistryStorage implements StorableObject {
|
||||
@@ -53,9 +53,4 @@ public final class DimensionRegistryStorage implements StorableObject {
|
||||
dimensions.clear();
|
||||
chatTypes.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearOnServerSwitch() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_20_2to1_20.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_20_2to1_20.Protocol1_20_2To1_20;
|
||||
import com.viaversion.viabackwards.protocol.v1_20_2to1_20.storage.ConfigurationPacketStorage;
|
||||
@@ -29,7 +30,6 @@ import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_20;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_20_2;
|
||||
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ClientboundPackets1_19_4;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.protocols.v1_20to1_20_2.packet.ClientboundPackets1_20_2;
|
||||
|
||||
public final class EntityPacketRewriter1_20_2 extends EntityRewriter<ClientboundPackets1_20_2, Protocol1_20_2To1_20> {
|
||||
|
||||
-5
@@ -21,9 +21,4 @@ import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
import java.util.UUID;
|
||||
|
||||
public record ResourcepackIDStorage(UUID uuid) implements StorableObject {
|
||||
|
||||
@Override
|
||||
public boolean clearOnServerSwitch() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-5
@@ -28,9 +28,4 @@ public final class CookieStorage implements StorableObject {
|
||||
public Map<String, byte[]> cookies() {
|
||||
return cookies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearOnServerSwitch() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -30,10 +30,10 @@ import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
|
||||
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ClientboundPackets1_19_4;
|
||||
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ServerboundPackets1_19_4;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.rewriter.text.ComponentRewriterBase;
|
||||
import com.viaversion.viaversion.util.ArrayUtil;
|
||||
|
||||
public final class Protocol1_20To1_19_4 extends BackwardsProtocol<ClientboundPackets1_19_4, ClientboundPackets1_19_4, ServerboundPackets1_19_4, ServerboundPackets1_19_4> {
|
||||
|
||||
+1
-1
@@ -17,9 +17,9 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_20to1_19_4.data;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
|
||||
import com.viaversion.viabackwards.api.data.BackwardsMappingDataLoader;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.protocols.v1_19_4to1_20.Protocol1_19_4To1_20;
|
||||
|
||||
public class BackwardsMappingData1_20 extends BackwardsMappingData {
|
||||
|
||||
+3
-3
@@ -18,6 +18,9 @@
|
||||
package com.viaversion.viabackwards.protocol.v1_20to1_19_4.rewriter;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_20to1_19_4.Protocol1_20To1_19_4;
|
||||
import com.viaversion.viaversion.api.minecraft.Quaternion;
|
||||
@@ -29,9 +32,6 @@ import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_19_4;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_20;
|
||||
import com.viaversion.viaversion.protocols.v1_19_3to1_19_4.packet.ClientboundPackets1_19_4;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
+14
-8
@@ -316,14 +316,7 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
|
||||
|
||||
// Player input no longer sets the sneaking state on the server
|
||||
// Send the change separately if needed (= when in a vehicle and player commands aren't sent by the old client)
|
||||
final PlayerStorage sneakingStorage = wrapper.user().get(PlayerStorage.class);
|
||||
if (sneakingStorage.setSneaking(sneaking)) {
|
||||
final PacketWrapper playerCommandPacket = wrapper.create(ServerboundPackets1_21_2.PLAYER_COMMAND);
|
||||
playerCommandPacket.write(Types.VAR_INT, tracker(wrapper.user()).clientEntityId());
|
||||
playerCommandPacket.write(Types.VAR_INT, sneaking ? 0 : 1); // Start/stop sneaking
|
||||
playerCommandPacket.write(Types.VAR_INT, 0); // Data
|
||||
playerCommandPacket.sendToServer(Protocol1_21_2To1_21.class);
|
||||
}
|
||||
sendSneakingPlayerCommand(wrapper, sneaking);
|
||||
});
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_20_5.MOVE_PLAYER_POS, wrapper -> {
|
||||
@@ -416,6 +409,7 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
|
||||
final ClientVehicleStorage storage = wrapper.user().get(ClientVehicleStorage.class);
|
||||
if (storage != null && vehicleId == storage.vehicleId()) {
|
||||
wrapper.user().remove(ClientVehicleStorage.class);
|
||||
sendSneakingPlayerCommand(wrapper, false);
|
||||
}
|
||||
|
||||
final int clientEntityId = tracker(wrapper.user()).clientEntityId();
|
||||
@@ -436,6 +430,7 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
|
||||
for (final int entityId : entityIds) {
|
||||
if (entityId == vehicleStorage.vehicleId()) {
|
||||
wrapper.user().remove(ClientVehicleStorage.class);
|
||||
sendSneakingPlayerCommand(wrapper, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -561,6 +556,17 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
|
||||
}
|
||||
}
|
||||
|
||||
private void sendSneakingPlayerCommand(final PacketWrapper wrapper, final boolean sneaking) {
|
||||
final PlayerStorage sneakingStorage = wrapper.user().get(PlayerStorage.class);
|
||||
if (sneakingStorage.setSneaking(sneaking)) {
|
||||
final PacketWrapper playerCommandPacket = wrapper.create(ServerboundPackets1_21_2.PLAYER_COMMAND);
|
||||
playerCommandPacket.write(Types.VAR_INT, tracker(wrapper.user()).clientEntityId());
|
||||
playerCommandPacket.write(Types.VAR_INT, sneaking ? 0 : 1); // Start/stop sneaking
|
||||
playerCommandPacket.write(Types.VAR_INT, 0); // Data
|
||||
playerCommandPacket.sendToServer(Protocol1_21_2To1_21.class);
|
||||
}
|
||||
}
|
||||
|
||||
private int boatTypeFromEntityType(final EntityType type) {
|
||||
if (type == EntityTypes1_21_2.OAK_BOAT) {
|
||||
return 0;
|
||||
|
||||
+1
-1
@@ -168,7 +168,7 @@ public final class RecipeStorage implements StorableObject {
|
||||
final String[] recipeKeys = new String[recipes.size()];
|
||||
final List<String> highlightRecipes = new ArrayList<>();
|
||||
for (int i = 0; i < recipes.size(); i++) {
|
||||
recipeKeys[i] = identifier(i);
|
||||
recipeKeys[i] = identifier(recipes.get(i).index);
|
||||
if (recipes.get(i).highlight) {
|
||||
highlightRecipes.add(recipeKeys[i]);
|
||||
}
|
||||
|
||||
+2
-1
@@ -55,6 +55,7 @@ import com.viaversion.viaversion.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.Limit;
|
||||
|
||||
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
|
||||
|
||||
@@ -160,7 +161,7 @@ public final class Protocol1_21_5To1_21_4 extends BackwardsProtocol<ClientboundP
|
||||
wrapper.passthrough(Types.STRING); // Command
|
||||
wrapper.passthrough(Types.LONG); // Timestamp
|
||||
wrapper.passthrough(Types.LONG); // Salt
|
||||
final int signatures = wrapper.passthrough(Types.VAR_INT);
|
||||
final int signatures = Limit.max(wrapper.passthrough(Types.VAR_INT), 8);
|
||||
for (int i = 0; i < signatures; i++) {
|
||||
wrapper.passthrough(Types.STRING); // Argument name
|
||||
wrapper.passthrough(Types.SIGNATURE_BYTES); // Signature
|
||||
|
||||
+14
-5
@@ -91,7 +91,7 @@ public final class BlockItemPacketRewriter1_21_5 extends BackwardsStructuredItem
|
||||
private static final int SIGN_BOCK_ENTITY_ID = 7;
|
||||
private static final int HANGING_SIGN_BOCK_ENTITY_ID = 8;
|
||||
private static final int SADDLE_EQUIPMENT_SLOT = 7;
|
||||
private static final byte SADDLED_FLAG = 4;
|
||||
static final byte SADDLED_FLAG = 4;
|
||||
|
||||
public BlockItemPacketRewriter1_21_5(final Protocol1_21_5To1_21_4 protocol) {
|
||||
super(protocol);
|
||||
@@ -187,7 +187,8 @@ public final class BlockItemPacketRewriter1_21_5 extends BackwardsStructuredItem
|
||||
final int equipmentSlot = value & 0x7F;
|
||||
if (equipmentSlot == SADDLE_EQUIPMENT_SLOT) {
|
||||
if (trackedEntity != null && trackedEntity.entityType().isOrHasParent(EntityTypes1_21_5.ABSTRACT_HORSE)) {
|
||||
sendSaddledEntityData(wrapper.user(), trackedEntity, entityId);
|
||||
final Item item = wrapper.read(itemType());
|
||||
sendSaddledEntityData(wrapper.user(), trackedEntity, entityId, item.identifier() == 800);
|
||||
}
|
||||
wrapper.cancel();
|
||||
return;
|
||||
@@ -268,16 +269,24 @@ public final class BlockItemPacketRewriter1_21_5 extends BackwardsStructuredItem
|
||||
wrapper.write(Types.STRING, namespace + ":textures/" + path + ".png");
|
||||
}
|
||||
|
||||
private void sendSaddledEntityData(final UserConnection connection, final TrackedEntity trackedEntity, final int entityId) {
|
||||
private void sendSaddledEntityData(final UserConnection connection, final TrackedEntity trackedEntity, final int entityId, final boolean saddled) {
|
||||
byte data = 0;
|
||||
if (trackedEntity.hasData()) {
|
||||
final HorseDataStorage horseDataStorage = trackedEntity.data().get(HorseDataStorage.class);
|
||||
if (horseDataStorage != null) {
|
||||
if (horseDataStorage.saddled() == saddled) {
|
||||
return;
|
||||
}
|
||||
|
||||
data = horseDataStorage.data();
|
||||
}
|
||||
}
|
||||
trackedEntity.data().put(new HorseDataStorage(data, true));
|
||||
data = (byte) (data | SADDLED_FLAG);
|
||||
|
||||
trackedEntity.data().put(new HorseDataStorage(data, saddled));
|
||||
|
||||
if (saddled) {
|
||||
data = (byte) (data | SADDLED_FLAG);
|
||||
}
|
||||
|
||||
final PacketWrapper entityDataPacket = PacketWrapper.create(ClientboundPackets1_21_2.SET_ENTITY_DATA, connection);
|
||||
final List<EntityData> entityDataList = new ArrayList<>();
|
||||
|
||||
+8
-1
@@ -81,7 +81,14 @@ public final class ComponentRewriter1_21_5 extends NBTComponentRewriter<Clientbo
|
||||
switch (action) {
|
||||
case "open_url" -> clickEventTag.put("value", clickEventTag.getStringTag("url"));
|
||||
case "change_page" -> clickEventTag.putString("value", Integer.toString(clickEventTag.getInt("page")));
|
||||
case "run_command", "suggest_command" -> clickEventTag.put("value", clickEventTag.getStringTag("command"));
|
||||
case "run_command" -> {
|
||||
final StringTag command = clickEventTag.getStringTag("command");
|
||||
if (command != null && !command.getValue().startsWith("/")) {
|
||||
command.setValue("/" + command.getValue());
|
||||
}
|
||||
clickEventTag.put("value", command);
|
||||
}
|
||||
case "suggest_command" -> clickEventTag.put("value", clickEventTag.getStringTag("command"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+35
-8
@@ -119,6 +119,12 @@ public final class EntityPacketRewriter1_21_5 extends EntityRewriter<Clientbound
|
||||
updateTrim(entries, trimPatternRegistry ? "template_item" : "ingredient");
|
||||
return super.handle(connection, key, entries);
|
||||
}
|
||||
|
||||
if (key.equals("enchantment")) {
|
||||
updateEnchantment(entries);
|
||||
return super.handle(connection, key, entries);
|
||||
}
|
||||
|
||||
if (!key.equals("wolf_variant")) {
|
||||
return super.handle(connection, key, entries);
|
||||
}
|
||||
@@ -209,6 +215,20 @@ public final class EntityPacketRewriter1_21_5 extends EntityRewriter<Clientbound
|
||||
});
|
||||
}
|
||||
|
||||
private void updateEnchantment(final RegistryEntry[] entries) {
|
||||
for (final RegistryEntry entry : entries) {
|
||||
if (entry.tag() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final CompoundTag enchantment = (CompoundTag) entry.tag();
|
||||
final ListTag<StringTag> slots = enchantment.getListTag("slots", StringTag.class);
|
||||
if (slots != null) {
|
||||
slots.getValue().removeIf(tag -> tag.getValue().equals("saddle")); // Remove saddle slot
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String visibility(final int id) {
|
||||
return switch (id) {
|
||||
case 0 -> "always";
|
||||
@@ -274,6 +294,11 @@ public final class EntityPacketRewriter1_21_5 extends EntityRewriter<Clientbound
|
||||
filter().type(EntityTypes1_21_5.ABSTRACT_MINECART).addIndex(13); // Custom display
|
||||
filter().type(EntityTypes1_21_5.ABSTRACT_MINECART).index(11).handler((event, data) -> {
|
||||
final int state = (int) data.getValue();
|
||||
if (state == 0) {
|
||||
event.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
final int mappedBlockState = protocol.getMappingData().getNewBlockStateId(state);
|
||||
data.setTypeAndValue(entityDataTypes.varIntType, mappedBlockState);
|
||||
event.createExtraData(new EntityData(13, mappedEntityDataTypes.booleanType, true));
|
||||
@@ -286,16 +311,18 @@ public final class EntityPacketRewriter1_21_5 extends EntityRewriter<Clientbound
|
||||
}));
|
||||
|
||||
filter().type(EntityTypes1_21_5.ABSTRACT_HORSE).index(17).handler((event, data) -> {
|
||||
// Store data for later
|
||||
// Store data and set saddled flag if needed
|
||||
final TrackedEntity entity = event.trackedEntity();
|
||||
if (entity.hasData()) {
|
||||
final HorseDataStorage horseDataStorage = entity.data().get(HorseDataStorage.class);
|
||||
if (horseDataStorage != null && horseDataStorage.saddled()) {
|
||||
entity.data().put(new HorseDataStorage(data.value(), true));
|
||||
return;
|
||||
}
|
||||
final byte horseData = data.value();
|
||||
boolean saddled = false;
|
||||
|
||||
final HorseDataStorage horseDataStorage;
|
||||
if (entity.hasData() && (horseDataStorage = entity.data().get(HorseDataStorage.class)) != null && horseDataStorage.saddled()) {
|
||||
saddled = true;
|
||||
data.setValue((byte) (horseData | BlockItemPacketRewriter1_21_5.SADDLED_FLAG));
|
||||
}
|
||||
entity.data().put(new HorseDataStorage(data.value(), false));
|
||||
|
||||
entity.data().put(new HorseDataStorage(horseData, saddled));
|
||||
});
|
||||
|
||||
filter().type(EntityTypes1_21_5.CHICKEN).cancel(17); // Chicken variant
|
||||
|
||||
+208
-7
@@ -17,15 +17,26 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
|
||||
import com.viaversion.viabackwards.api.rewriters.SoundRewriter;
|
||||
import com.viaversion.viabackwards.api.rewriters.text.NBTComponentRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.Dialog;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.provider.ChestDialogViewProvider;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.provider.DialogViewProvider;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.rewriter.BlockItemPacketRewriter1_21_6;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.rewriter.ComponentRewriter1_21_6;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.rewriter.EntityPacketRewriter1_21_6;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ChestDialogStorage;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ClickEvents;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.RegistryAndTags;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ServerLinks;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_6;
|
||||
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
|
||||
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
|
||||
@@ -52,6 +63,7 @@ import com.viaversion.viaversion.rewriter.AttributeRewriter;
|
||||
import com.viaversion.viaversion.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.SerializerVersion;
|
||||
|
||||
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
|
||||
@@ -73,14 +85,27 @@ public final class Protocol1_21_6To1_21_5 extends BackwardsProtocol<ClientboundP
|
||||
protected void registerPackets() {
|
||||
super.registerPackets();
|
||||
|
||||
tagRewriter.removeTags("dialog");
|
||||
tagRewriter.registerGeneric(ClientboundPackets1_21_6.UPDATE_TAGS);
|
||||
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21_6.UPDATE_TAGS);
|
||||
registerClientbound(ClientboundPackets1_21_6.UPDATE_TAGS, this::updateTags);
|
||||
registerClientbound(ClientboundConfigurationPackets1_21_6.UPDATE_TAGS, this::updateTags);
|
||||
|
||||
final SoundRewriter<ClientboundPacket1_21_6> soundRewriter = new SoundRewriter<>(this);
|
||||
soundRewriter.registerSound1_19_3(ClientboundPackets1_21_6.SOUND);
|
||||
appendClientbound(ClientboundPackets1_21_6.SOUND, wrapper -> {
|
||||
wrapper.passthrough(Types.VAR_INT); // Source
|
||||
fixSoundSource(wrapper);
|
||||
});
|
||||
soundRewriter.registerSound1_19_3(ClientboundPackets1_21_6.SOUND_ENTITY);
|
||||
appendClientbound(ClientboundPackets1_21_6.SOUND_ENTITY, wrapper -> {
|
||||
wrapper.passthrough(Types.VAR_INT); // Source
|
||||
fixSoundSource(wrapper);
|
||||
});
|
||||
soundRewriter.registerStopSound(ClientboundPackets1_21_6.STOP_SOUND);
|
||||
appendClientbound(ClientboundPackets1_21_6.STOP_SOUND, wrapper -> {
|
||||
final byte flags = wrapper.get(Types.BYTE, 0);
|
||||
if ((flags & 0x01) != 0) {
|
||||
fixSoundSource(wrapper);
|
||||
}
|
||||
});
|
||||
|
||||
new StatisticsRewriter<>(this).register(ClientboundPackets1_21_6.AWARD_STATS);
|
||||
new AttributeRewriter<>(this).register1_21(ClientboundPackets1_21_6.UPDATE_ATTRIBUTES);
|
||||
@@ -112,17 +137,193 @@ public final class Protocol1_21_6To1_21_5 extends BackwardsProtocol<ClientboundP
|
||||
particleRewriter.registerLevelParticles1_21_4(ClientboundPackets1_21_6.LEVEL_PARTICLES);
|
||||
particleRewriter.registerExplode1_21_2(ClientboundPackets1_21_6.EXPLODE);
|
||||
|
||||
registerClientbound(ClientboundPackets1_21_6.CHANGE_DIFFICULTY, wrapper -> {
|
||||
final int difficulty = wrapper.read(Types.VAR_INT);
|
||||
wrapper.write(Types.UNSIGNED_BYTE, (short) difficulty);
|
||||
});
|
||||
registerServerbound(ServerboundPackets1_21_5.CHANGE_DIFFICULTY, wrapper -> {
|
||||
final short difficulty = wrapper.read(Types.UNSIGNED_BYTE);
|
||||
wrapper.write(Types.VAR_INT, (int) difficulty);
|
||||
});
|
||||
|
||||
// Are you sure you want to see this? This is your last chance to turn back.
|
||||
registerClientbound(ClientboundPackets1_21_6.SHOW_DIALOG, null, wrapper -> {
|
||||
wrapper.cancel();
|
||||
|
||||
final RegistryAndTags registryAndTags = wrapper.user().get(RegistryAndTags.class);
|
||||
final ServerLinks serverLinks = wrapper.user().get(ServerLinks.class);
|
||||
final int id = wrapper.read(Types.VAR_INT) - 1;
|
||||
CompoundTag tag;
|
||||
if (id == -1) {
|
||||
tag = (CompoundTag) wrapper.read(Types.TAG);
|
||||
} else {
|
||||
tag = registryAndTags.fromRegistry(id);
|
||||
}
|
||||
|
||||
final DialogViewProvider provider = Via.getManager().getProviders().get(DialogViewProvider.class);
|
||||
provider.openDialog(wrapper.user(), new Dialog(registryAndTags, serverLinks, tag));
|
||||
});
|
||||
registerClientbound(ClientboundConfigurationPackets1_21_6.SHOW_DIALOG, null, wrapper -> {
|
||||
wrapper.cancel();
|
||||
|
||||
final RegistryAndTags registryAndTags = wrapper.user().get(RegistryAndTags.class);
|
||||
final ServerLinks serverLinks = wrapper.user().get(ServerLinks.class);
|
||||
final CompoundTag tag = (CompoundTag) wrapper.read(Types.TAG);
|
||||
|
||||
final DialogViewProvider provider = Via.getManager().getProviders().get(DialogViewProvider.class);
|
||||
provider.openDialog(wrapper.user(), new Dialog(registryAndTags, serverLinks, tag));
|
||||
});
|
||||
registerClientbound(ClientboundPackets1_21_6.CLEAR_DIALOG, null, this::clearDialog);
|
||||
registerClientbound(ClientboundConfigurationPackets1_21_6.CLEAR_DIALOG, null, this::clearDialog);
|
||||
|
||||
registerClientbound(ClientboundPackets1_21_6.SERVER_LINKS, this::storeServerLinks);
|
||||
registerClientbound(ClientboundConfigurationPackets1_21_6.SERVER_LINKS, this::storeServerLinks);
|
||||
|
||||
registerServerbound(ServerboundPackets1_21_5.CHAT_COMMAND, wrapper -> {
|
||||
final String command = wrapper.passthrough(Types.STRING);
|
||||
|
||||
final ClickEvents clickEvents = wrapper.user().get(ClickEvents.class);
|
||||
if (clickEvents.handleChatCommand(wrapper.user(), command)) {
|
||||
wrapper.cancel();
|
||||
}
|
||||
});
|
||||
|
||||
// The ones below are specific to the chest dialog view provider
|
||||
registerServerbound(ServerboundPackets1_21_5.CONTAINER_CLOSE, wrapper -> {
|
||||
final ChestDialogStorage storage = wrapper.user().get(ChestDialogStorage.class);
|
||||
if (storage == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ChestDialogViewProvider provider = (ChestDialogViewProvider) Via.getManager().getProviders().get(DialogViewProvider.class);
|
||||
if (storage.phase() == ChestDialogStorage.Phase.ANVIL_VIEW) {
|
||||
wrapper.cancel();
|
||||
provider.openChestView(wrapper.user(), storage, ChestDialogStorage.Phase.DIALOG_VIEW);
|
||||
return;
|
||||
}
|
||||
if (storage.phase() == ChestDialogStorage.Phase.WAITING_FOR_RESPONSE) {
|
||||
wrapper.cancel();
|
||||
if (storage.closeButtonEnabled()) {
|
||||
provider.openChestView(wrapper.user(), storage, ChestDialogStorage.Phase.DIALOG_VIEW);
|
||||
} else {
|
||||
provider.openChestView(wrapper.user(), storage, ChestDialogStorage.Phase.WAITING_FOR_RESPONSE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean allowClosing = storage.allowClosing();
|
||||
if (!allowClosing) {
|
||||
wrapper.cancel();
|
||||
if (storage.dialog().canCloseWithEscape()) {
|
||||
provider.clickButton(wrapper.user(), Dialog.AfterAction.CLOSE, storage.dialog().actionButton());
|
||||
} else {
|
||||
provider.openChestView(wrapper.user(), storage, ChestDialogStorage.Phase.DIALOG_VIEW);
|
||||
}
|
||||
}
|
||||
storage.setAllowClosing(false);
|
||||
});
|
||||
registerServerbound(ServerboundPackets1_21_5.RENAME_ITEM, wrapper -> {
|
||||
final ChestDialogStorage storage = wrapper.user().get(ChestDialogStorage.class);
|
||||
if (storage == null || storage.phase() != ChestDialogStorage.Phase.ANVIL_VIEW) {
|
||||
return;
|
||||
}
|
||||
|
||||
wrapper.cancel();
|
||||
final String name = wrapper.read(Types.STRING);
|
||||
|
||||
final ChestDialogViewProvider provider = (ChestDialogViewProvider) Via.getManager().getProviders().get(DialogViewProvider.class);
|
||||
provider.updateAnvilText(wrapper.user(), name);
|
||||
});
|
||||
appendServerbound(ServerboundPackets1_21_5.CONTAINER_CLICK, wrapper -> {
|
||||
final ChestDialogViewProvider provider = (ChestDialogViewProvider) Via.getManager().getProviders().get(DialogViewProvider.class);
|
||||
if (provider == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int containerId = wrapper.get(Types.VAR_INT, 0);
|
||||
final int slot = wrapper.get(Types.SHORT, 0);
|
||||
final byte button = wrapper.get(Types.BYTE, 0);
|
||||
final int mode = wrapper.get(Types.VAR_INT, 2);
|
||||
if (provider.clickDialog(wrapper.user(), containerId, slot, button, mode)) {
|
||||
wrapper.cancel();
|
||||
}
|
||||
});
|
||||
|
||||
cancelClientbound(ClientboundPackets1_21_6.TRACKED_WAYPOINT);
|
||||
cancelClientbound(ClientboundPackets1_21_6.CLEAR_DIALOG);
|
||||
cancelClientbound(ClientboundPackets1_21_6.SHOW_DIALOG);
|
||||
cancelClientbound(ClientboundConfigurationPackets1_21_6.CLEAR_DIALOG);
|
||||
cancelClientbound(ClientboundConfigurationPackets1_21_6.SHOW_DIALOG);
|
||||
}
|
||||
|
||||
private void fixSoundSource(final PacketWrapper wrapper) {
|
||||
final int source = wrapper.get(Types.VAR_INT, 0);
|
||||
if (source == 10) { // New ui source, map to master
|
||||
wrapper.set(Types.VAR_INT, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTags(final PacketWrapper wrapper) {
|
||||
tagRewriter.handleGeneric(wrapper);
|
||||
wrapper.resetReader();
|
||||
|
||||
final RegistryAndTags registryAndTags = wrapper.user().get(RegistryAndTags.class);
|
||||
final int length = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < length; i++) {
|
||||
final String registryKey = wrapper.read(Types.STRING);
|
||||
final boolean dialog = "dialog".equals(Key.stripMinecraftNamespace(registryKey));
|
||||
if (dialog) {
|
||||
final int tagsSize = wrapper.read(Types.VAR_INT);
|
||||
for (int j = 0; j < tagsSize; j++) {
|
||||
final String key = wrapper.read(Types.STRING);
|
||||
final int[] ids = wrapper.read(Types.VAR_INT_ARRAY_PRIMITIVE);
|
||||
registryAndTags.storeTags(key, ids);
|
||||
}
|
||||
} else {
|
||||
wrapper.write(Types.STRING, registryKey); // Write back
|
||||
final int tagsSize = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int j = 0; j < tagsSize; j++) {
|
||||
wrapper.passthrough(Types.STRING);
|
||||
wrapper.passthrough(Types.VAR_INT_ARRAY_PRIMITIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (registryAndTags.tagsSent()) {
|
||||
wrapper.set(Types.VAR_INT, 0, length - 1); // Dialog tags have been read, remove from size
|
||||
}
|
||||
}
|
||||
|
||||
private void clearDialog(final PacketWrapper wrapper) {
|
||||
wrapper.cancel();
|
||||
final DialogViewProvider provider = Via.getManager().getProviders().get(DialogViewProvider.class);
|
||||
provider.closeDialog(wrapper.user());
|
||||
}
|
||||
|
||||
private void storeServerLinks(final PacketWrapper wrapper) {
|
||||
final ServerLinks serverLinks = new ServerLinks();
|
||||
final int length = wrapper.passthrough(Types.VAR_INT);
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (wrapper.passthrough(Types.BOOLEAN)) {
|
||||
final int id = wrapper.passthrough(Types.VAR_INT);
|
||||
final String url = wrapper.passthrough(Types.STRING);
|
||||
serverLinks.storeLink(id, url);
|
||||
} else {
|
||||
final Tag tag = wrapper.passthrough(Types.COMPOUND_TAG);
|
||||
final String url = wrapper.passthrough(Types.STRING);
|
||||
serverLinks.storeLink(tag, url);
|
||||
}
|
||||
}
|
||||
wrapper.user().put(serverLinks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(final UserConnection user) {
|
||||
addEntityTracker(user, new EntityTrackerBase(user, EntityTypes1_21_6.PLAYER));
|
||||
addItemHasher(user, new ItemHasherBase(this, user, SerializerVersion.V1_21_5, SerializerVersion.V1_21_5));
|
||||
user.put(new RegistryAndTags());
|
||||
user.put(new ClickEvents());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(final ViaProviders providers) {
|
||||
providers.register(DialogViewProvider.class, new ChestDialogViewProvider(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input.Input;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.widget.Widget;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class Button implements Widget {
|
||||
|
||||
public static final Button DEFAULT = defaulted();
|
||||
private static final String[] CLICK_EVENTS = {
|
||||
"open_url",
|
||||
"run_command",
|
||||
"suggest_command",
|
||||
"show_dialog",
|
||||
"change_page",
|
||||
"copy_to_clipboard",
|
||||
"custom"
|
||||
};
|
||||
|
||||
private final Dialog dialog;
|
||||
private final Tag label;
|
||||
private final int width;
|
||||
|
||||
private final @Nullable Tag tooltip;
|
||||
private @Nullable CompoundTag clickEvent;
|
||||
|
||||
private @Nullable Template template;
|
||||
|
||||
private @Nullable String id;
|
||||
private @Nullable CompoundTag additions;
|
||||
|
||||
public Button(final Dialog dialog, final CompoundTag tag) {
|
||||
this.dialog = dialog;
|
||||
this.label = tag.get("label");
|
||||
this.tooltip = tag.get("tooltip");
|
||||
|
||||
final int width = tag.getInt("width", 150);
|
||||
if (width < 1 || width > 1024) {
|
||||
throw new IllegalArgumentException("Width must be between 1 and 1024, got: " + width);
|
||||
}
|
||||
this.width = width;
|
||||
|
||||
final CompoundTag actionTag = tag.getCompoundTag("action");
|
||||
if (actionTag == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String type = actionTag.getString("type");
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("Action type is missing in tag: " + tag);
|
||||
}
|
||||
|
||||
for (final String event : CLICK_EVENTS) {
|
||||
if (Key.stripMinecraftNamespace(type).equals(event)) {
|
||||
clickEvent = actionTag;
|
||||
clickEvent.put("action", clickEvent.remove("type"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Key.stripMinecraftNamespace(type).equals("dynamic/run_command")) {
|
||||
template = Template.fromString(actionTag.getString("template"));
|
||||
} else if (Key.stripMinecraftNamespace(type).equals("dynamic/custom")) {
|
||||
id = actionTag.getString("id");
|
||||
additions = actionTag.getCompoundTag("additions");
|
||||
}
|
||||
}
|
||||
|
||||
private static Button defaulted() {
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
final CompoundTag label = new CompoundTag();
|
||||
tag.put("label", label);
|
||||
label.putString("translate", "gui.ok");
|
||||
|
||||
return new Button(null, tag);
|
||||
}
|
||||
|
||||
public static Button openUrl(final Tag label, final String url) {
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
final CompoundTag actionTag = new CompoundTag();
|
||||
final CompoundTag openUrlTag = new CompoundTag();
|
||||
|
||||
tag.put("label", label);
|
||||
tag.put("action", actionTag);
|
||||
actionTag.putString("type", "open_url");
|
||||
actionTag.put("action", openUrlTag);
|
||||
openUrlTag.putString("url", url);
|
||||
return new Button(null, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a click event for this button based on the provided inputs.
|
||||
*
|
||||
* @return a CompoundTag representing the click event, which can be used in a button action.
|
||||
*/
|
||||
public @Nullable CompoundTag clickEvent() {
|
||||
if (clickEvent != null) {
|
||||
return clickEvent;
|
||||
}
|
||||
|
||||
if (dialog == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Input[] inputs = dialog.widgets()
|
||||
.stream()
|
||||
.filter(widget -> widget instanceof Input)
|
||||
.toArray(Input[]::new);
|
||||
|
||||
if (template != null) {
|
||||
final Map<String, String> substitutions = new HashMap<>();
|
||||
for (final Input input : inputs) {
|
||||
substitutions.put(input.key(), input.asCommandSubstitution());
|
||||
}
|
||||
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
tag.putString("action", "run_command");
|
||||
tag.putString("command", template.instantiate(substitutions));
|
||||
return tag;
|
||||
}
|
||||
|
||||
if (id != null) {
|
||||
final CompoundTag additions = this.additions != null ? this.additions.copy() : new CompoundTag();
|
||||
for (final Input input : inputs) {
|
||||
additions.put(input.key(), input.asTag());
|
||||
}
|
||||
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
tag.putString("action", "custom");
|
||||
tag.putString("id", id);
|
||||
tag.put("payload", additions);
|
||||
return tag;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Tag label() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public @Nullable Tag tooltip() {
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
public int width() {
|
||||
return width;
|
||||
}
|
||||
}
|
||||
+253
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input.BooleanInput;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input.NumberRangeInput;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input.SingleOptionInput;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input.TextInput;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.widget.ItemWidget;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.widget.TextWidget;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.widget.Widget;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.provider.ChestDialogViewProvider;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.RegistryAndTags;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ServerLinks;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* The dialog structure. See the used subclasses for further details on the
|
||||
* specific structure. Note that the data hold here is directly from the server
|
||||
* and needs to be remapped manually when used. See {@link ChestDialogViewProvider} for an example
|
||||
*/
|
||||
public final class Dialog implements Widget {
|
||||
|
||||
private final List<Widget> widgets = new ArrayList<>();
|
||||
private final Tag title;
|
||||
private final @Nullable Tag externalTitle;
|
||||
private final boolean canCloseWithEscape;
|
||||
private final AfterAction afterAction;
|
||||
|
||||
private @Nullable Button actionButton;
|
||||
private @Nullable Button yesButton;
|
||||
private @Nullable Button noButton;
|
||||
|
||||
private int columns;
|
||||
private int buttonWidth;
|
||||
|
||||
public Dialog(final RegistryAndTags registryAndTags, final ServerLinks serverLinks, final CompoundTag tag) {
|
||||
final String type = tag.getString("type");
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("Dialog type is missing in tag: " + tag);
|
||||
}
|
||||
|
||||
this.title = tag.get("title");
|
||||
this.externalTitle = tag.get("external_title");
|
||||
this.canCloseWithEscape = tag.getBoolean("can_close_with_escape", true);
|
||||
this.afterAction = AfterAction.valueOf(tag.getString("after_action", "close").toUpperCase(Locale.ROOT));
|
||||
|
||||
ListTag<CompoundTag> bodyListTag = tag.getListTag("body", CompoundTag.class);
|
||||
if (bodyListTag == null) {
|
||||
CompoundTag bodyTag = tag.getCompoundTag("body");
|
||||
if (bodyTag != null) {
|
||||
bodyListTag = new ListTag<>(CompoundTag.class);
|
||||
bodyListTag.add(bodyTag);
|
||||
}
|
||||
}
|
||||
if (bodyListTag != null) {
|
||||
for (final CompoundTag bodyTag : bodyListTag) {
|
||||
fillBodyWidget(bodyTag);
|
||||
}
|
||||
}
|
||||
|
||||
final ListTag<CompoundTag> inputListTag = tag.getListTag("inputs", CompoundTag.class);
|
||||
if (inputListTag != null) {
|
||||
for (final CompoundTag inputTag : inputListTag) {
|
||||
fillInputWidget(inputTag);
|
||||
}
|
||||
}
|
||||
|
||||
switch (Key.stripMinecraftNamespace(type)) {
|
||||
case "notice" -> fillNoticeDialog(tag);
|
||||
case "server_links" -> fillServerLinksDialog(serverLinks, tag);
|
||||
case "dialog_list" -> fillDialogList(registryAndTags, serverLinks, tag);
|
||||
case "multi_action" -> fillMultiActionDialog(tag);
|
||||
case "confirmation" -> fillConfirmationDialog(tag);
|
||||
default -> throw new IllegalArgumentException("Unknown dialog type: " + type + " in tag: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
private void fillBodyWidget(final CompoundTag tag) {
|
||||
final String type = tag.getString("type");
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("Dialog type is missing in tag: " + tag);
|
||||
}
|
||||
|
||||
if (Key.stripMinecraftNamespace(type).equals("plain_message")) {
|
||||
widgets.add(new TextWidget(tag));
|
||||
} else if (Key.stripMinecraftNamespace(type).equals("item")) {
|
||||
widgets.add(new ItemWidget(tag));
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown dialog body type: " + type + " in tag: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
private void fillInputWidget(final CompoundTag tag) {
|
||||
final String type = tag.getString("type");
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("Dialog type is missing in tag: " + tag);
|
||||
}
|
||||
|
||||
widgets.add(switch (Key.stripMinecraftNamespace(type)) {
|
||||
case "boolean" -> new BooleanInput(tag);
|
||||
case "number_range" -> new NumberRangeInput(tag);
|
||||
case "single_option" -> new SingleOptionInput(tag);
|
||||
case "text" -> new TextInput(tag);
|
||||
default -> throw new IllegalArgumentException("Unknown dialog input type: " + type + " in tag: " + tag);
|
||||
});
|
||||
}
|
||||
|
||||
private void fillNoticeDialog(final CompoundTag tag) {
|
||||
final CompoundTag actionTag = tag.getCompoundTag("action");
|
||||
actionButton = actionTag == null ? Button.DEFAULT : actionButton;
|
||||
}
|
||||
|
||||
private void fillServerLinksDialog(final ServerLinks serverLinks, final CompoundTag tag) {
|
||||
fillDialogBase(tag);
|
||||
buttonWidth = tag.getInt("button_width", 150);
|
||||
|
||||
if (serverLinks == null) {
|
||||
return;
|
||||
}
|
||||
for (final Map.Entry<Tag, String> entry : serverLinks.links().entrySet()) {
|
||||
final Tag label = entry.getKey();
|
||||
final String url = entry.getValue();
|
||||
widgets.add(Button.openUrl(label, url));
|
||||
}
|
||||
}
|
||||
|
||||
private void fillDialogList(final RegistryAndTags registryAndTags, final ServerLinks serverLinks, final CompoundTag tag) {
|
||||
// Hold them as either a list of inlined, a singleton inlined, a registry entry or a tag.
|
||||
ListTag<CompoundTag> dialogsTag = tag.getListTag("dialogs", CompoundTag.class);
|
||||
if (dialogsTag == null) {
|
||||
CompoundTag dialogTag = tag.getCompoundTag("dialogs");
|
||||
if (dialogTag != null) {
|
||||
dialogsTag = new ListTag<>(CompoundTag.class);
|
||||
dialogsTag.add(dialogTag);
|
||||
}
|
||||
|
||||
StringTag registryDialogTag = tag.getStringTag("dialogs");
|
||||
if (registryDialogTag != null) {
|
||||
dialogsTag = new ListTag<>(CompoundTag.class);
|
||||
final String key = registryDialogTag.getValue();
|
||||
if (key.startsWith("#")) {
|
||||
for (final CompoundTag entry : registryAndTags.fromRegistryKey(key.substring(1))) {
|
||||
dialogsTag.add(entry);
|
||||
}
|
||||
} else {
|
||||
dialogsTag.add(registryAndTags.fromRegistry(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
widgets.addAll(dialogsTag.stream().map(dialog -> new Dialog(registryAndTags, serverLinks, dialog)).toList());
|
||||
|
||||
fillDialogBase(tag);
|
||||
buttonWidth = tag.getInt("button_width", 150);
|
||||
}
|
||||
|
||||
private void fillDialogBase(final CompoundTag tag) {
|
||||
final CompoundTag exitActionTag = tag.getCompoundTag("exit_action");
|
||||
actionButton = exitActionTag == null ? null : new Button(this, exitActionTag);
|
||||
|
||||
final int columns = tag.getInt("columns", 2);
|
||||
if (columns < 1) {
|
||||
throw new IllegalArgumentException("Columns must be non-negative, got: " + columns);
|
||||
}
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
private void fillMultiActionDialog(final CompoundTag tag) {
|
||||
final ListTag<CompoundTag> actionsTag = tag.getListTag("actions", CompoundTag.class);
|
||||
if (actionsTag == null || actionsTag.isEmpty()) {
|
||||
throw new IllegalArgumentException("Actions must not be empty in tag: " + tag);
|
||||
}
|
||||
widgets.addAll(actionsTag.stream().map(actionTag -> new Button(this, actionTag)).toList());
|
||||
|
||||
fillDialogBase(tag);
|
||||
}
|
||||
|
||||
private void fillConfirmationDialog(final CompoundTag tag) {
|
||||
yesButton = new Button(this, tag.getCompoundTag("yes"));
|
||||
noButton = new Button(this, tag.getCompoundTag("no"));
|
||||
}
|
||||
|
||||
public Tag title() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public @Nullable Tag externalTitle() {
|
||||
return externalTitle;
|
||||
}
|
||||
|
||||
public boolean canCloseWithEscape() {
|
||||
return canCloseWithEscape;
|
||||
}
|
||||
|
||||
public AfterAction afterAction() {
|
||||
return afterAction;
|
||||
}
|
||||
|
||||
public enum AfterAction {
|
||||
CLOSE,
|
||||
NONE,
|
||||
WAIT_FOR_RESPONSE
|
||||
}
|
||||
|
||||
public @Nullable Button actionButton() {
|
||||
return actionButton;
|
||||
}
|
||||
|
||||
public @Nullable Button yesButton() {
|
||||
return yesButton;
|
||||
}
|
||||
|
||||
public @Nullable Button noButton() {
|
||||
return noButton;
|
||||
}
|
||||
|
||||
public int columns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
public int buttonWidth() {
|
||||
return buttonWidth;
|
||||
}
|
||||
|
||||
public List<Widget> widgets() {
|
||||
return widgets;
|
||||
}
|
||||
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public record Template(List<String> segments, List<String> variables) {
|
||||
|
||||
private static final int MAX_LENGTH = 2000000;
|
||||
|
||||
public static Template fromString(final String string) {
|
||||
final Builder<String> segmentsBuilder = ImmutableList.builder();
|
||||
final Builder<String> variablesBuilder = ImmutableList.builder();
|
||||
int currentIndex = 0;
|
||||
int dollarIndex = string.indexOf('$');
|
||||
|
||||
while (dollarIndex != -1) {
|
||||
if (dollarIndex != string.length() - 1 && string.charAt(dollarIndex + 1) == '(') {
|
||||
segmentsBuilder.add(string.substring(currentIndex, dollarIndex));
|
||||
|
||||
final int closingParenIndex = string.indexOf(41, dollarIndex + 1);
|
||||
if (closingParenIndex == -1) {
|
||||
throw new IllegalArgumentException("Unterminated macro variable");
|
||||
}
|
||||
|
||||
final String variableName = string.substring(dollarIndex + 2, closingParenIndex);
|
||||
if (!isValidVariableName(variableName)) {
|
||||
throw new IllegalArgumentException("Invalid macro variable name '" + variableName + "'");
|
||||
}
|
||||
|
||||
variablesBuilder.add(variableName);
|
||||
currentIndex = closingParenIndex + 1;
|
||||
dollarIndex = string.indexOf(36, currentIndex);
|
||||
} else {
|
||||
dollarIndex = string.indexOf(36, dollarIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentIndex == 0) {
|
||||
throw new IllegalArgumentException("No variables in macro");
|
||||
}
|
||||
if (currentIndex != string.length()) {
|
||||
segmentsBuilder.add(string.substring(currentIndex));
|
||||
}
|
||||
return new Template(segmentsBuilder.build(), variablesBuilder.build());
|
||||
}
|
||||
|
||||
private static boolean isValidVariableName(final String string) {
|
||||
for (int i = 0; i < string.length(); i++) {
|
||||
final char c = string.charAt(i);
|
||||
if (!Character.isLetterOrDigit(c) && c != '_') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public String instantiate(final Map<String, String> map) {
|
||||
return substitute(variables().stream().map(string -> map.getOrDefault(string, "")).toList());
|
||||
}
|
||||
|
||||
private String substitute(final List<String> list) {
|
||||
final StringBuilder out = new StringBuilder();
|
||||
for (int i = 0; i < this.variables.size(); i++) {
|
||||
out.append(this.segments.get(i)).append(list.get(i));
|
||||
if (out.length() > MAX_LENGTH) {
|
||||
throw new IllegalArgumentException("Output too long (> " + MAX_LENGTH + ")");
|
||||
}
|
||||
}
|
||||
if (this.segments.size() > this.variables.size()) {
|
||||
out.append(this.segments.get(this.segments.size() - 1));
|
||||
if (out.length() > MAX_LENGTH) {
|
||||
throw new IllegalArgumentException("Output too long (> " + MAX_LENGTH + ")");
|
||||
}
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input;
|
||||
|
||||
import com.viaversion.nbt.tag.ByteTag;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
|
||||
public final class BooleanInput implements Input {
|
||||
|
||||
private final String key;
|
||||
private final Tag label;
|
||||
private final boolean initial;
|
||||
private final String onTrue;
|
||||
private final String onFalse;
|
||||
|
||||
private boolean value;
|
||||
|
||||
public BooleanInput(final CompoundTag tag) {
|
||||
this.key = tag.getString("key");
|
||||
this.label = tag.get("label");
|
||||
this.initial = tag.getBoolean("initial", false);
|
||||
this.onTrue = tag.getString("on_true", "true");
|
||||
this.onFalse = tag.getString("on_false", "false");
|
||||
|
||||
this.value = initial;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String key() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asCommandSubstitution() {
|
||||
return value ? onTrue : onFalse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag asTag() {
|
||||
return new ByteTag(value);
|
||||
}
|
||||
|
||||
public Tag label() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public boolean initial() {
|
||||
return initial;
|
||||
}
|
||||
|
||||
public String onTrue() {
|
||||
return onTrue;
|
||||
}
|
||||
|
||||
public String onFalse() {
|
||||
return onFalse;
|
||||
}
|
||||
|
||||
public boolean value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(final boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input;
|
||||
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.widget.Widget;
|
||||
|
||||
public interface Input extends Widget {
|
||||
|
||||
String key();
|
||||
|
||||
String asCommandSubstitution();
|
||||
|
||||
Tag asTag();
|
||||
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.FloatTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
|
||||
import static com.viaversion.viabackwards.utils.ChatUtil.text;
|
||||
import static com.viaversion.viabackwards.utils.ChatUtil.translate;
|
||||
|
||||
public final class NumberRangeInput implements Input {
|
||||
|
||||
private final String key;
|
||||
private final Tag label;
|
||||
private final String labelFormat;
|
||||
private final float start;
|
||||
private final float end;
|
||||
private final Float initial;
|
||||
private final Float step;
|
||||
|
||||
private float value;
|
||||
|
||||
public NumberRangeInput(final CompoundTag tag) {
|
||||
this.key = tag.getString("key");
|
||||
this.label = tag.get("label");
|
||||
this.labelFormat = tag.getString("label_format", "options.generic_value");
|
||||
this.start = tag.getFloat("start");
|
||||
this.end = tag.getFloat("end");
|
||||
this.initial = tag.getFloat("initial", (this.start + this.end) / 2F);
|
||||
final FloatTag stepTag = tag.getFloatTag("step");
|
||||
if (stepTag != null && stepTag.asFloat() < 0F) {
|
||||
throw new IllegalArgumentException("Step must be non-negative, got: " + stepTag.asFloat());
|
||||
}
|
||||
this.step = stepTag == null ? -1F : stepTag.asFloat();
|
||||
|
||||
this.value = initial;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String key() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asCommandSubstitution() {
|
||||
return valueAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag asTag() {
|
||||
return new FloatTag(value);
|
||||
}
|
||||
|
||||
public Tag label() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public String labelFormat() {
|
||||
return labelFormat;
|
||||
}
|
||||
|
||||
public float start() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public float end() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public float initial() {
|
||||
return initial;
|
||||
}
|
||||
|
||||
public float step() {
|
||||
return step;
|
||||
}
|
||||
|
||||
public float value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public String valueAsString() {
|
||||
final int asInt = (int) value;
|
||||
return asInt == value ? Integer.toString(asInt) : Float.toString(value);
|
||||
}
|
||||
|
||||
public void setValue(final float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void setClampedValue(final float value) {
|
||||
this.value = (value < start) ? start : Math.min(value, end);
|
||||
}
|
||||
|
||||
public Tag displayName() {
|
||||
return translate(labelFormat, label, text(valueAsString()));
|
||||
}
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import java.util.Objects;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class SingleOptionInput implements Input {
|
||||
|
||||
private final String key;
|
||||
private final Entry[] options;
|
||||
private final @Nullable Tag label;
|
||||
|
||||
private int value;
|
||||
|
||||
public SingleOptionInput(final CompoundTag tag) {
|
||||
final ListTag<CompoundTag> options = tag.getListTag("options", CompoundTag.class);
|
||||
if (options == null || options.isEmpty()) {
|
||||
throw new IllegalArgumentException("Options must not be empty in tag: " + tag);
|
||||
}
|
||||
|
||||
this.key = tag.getString("key");
|
||||
this.options = options.stream().map(Entry::new).toArray(Entry[]::new);
|
||||
this.label = tag.getBoolean("label_visible", true) ? tag.get("label") : null;
|
||||
|
||||
for (int i = 0; i < this.options.length; i++) {
|
||||
if (this.options[i].initial()) {
|
||||
if (this.value != 0) {
|
||||
throw new IllegalArgumentException("Multiple initial options found in tag: " + tag);
|
||||
}
|
||||
this.value = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String key() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asCommandSubstitution() {
|
||||
return this.options[value].id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag asTag() {
|
||||
return new StringTag(asCommandSubstitution());
|
||||
}
|
||||
|
||||
public Entry[] options() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public @Nullable Tag label() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public int value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(final int value) {
|
||||
if (value < 0 || value >= options.length) {
|
||||
throw new IllegalArgumentException("Value must be between 0 and " + (options.length - 1));
|
||||
}
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void setClampedValue(final int value) {
|
||||
if (value < 0) {
|
||||
this.value = 0;
|
||||
} else if (value >= options.length) {
|
||||
this.value = 0;
|
||||
} else {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Entry {
|
||||
private final String id;
|
||||
private final Tag display;
|
||||
private final boolean initial;
|
||||
|
||||
public Entry(final CompoundTag tag) {
|
||||
id = tag.getString("id");
|
||||
display = tag.get("display");
|
||||
initial = tag.getBoolean("initial", false);
|
||||
}
|
||||
|
||||
public String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Tag display() {
|
||||
return display;
|
||||
}
|
||||
|
||||
public boolean initial() {
|
||||
return initial;
|
||||
}
|
||||
|
||||
public Tag computeDisplay() {
|
||||
return Objects.requireNonNullElseGet(display, () -> new StringTag(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.IntTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class TextInput implements Input {
|
||||
|
||||
private final String key;
|
||||
private final @Nullable Tag label;
|
||||
private final String initial;
|
||||
private final int maxLength;
|
||||
private final @Nullable MultilineOptions[] options;
|
||||
|
||||
private String value;
|
||||
|
||||
public TextInput(final CompoundTag tag) {
|
||||
this.key = tag.getString("key");
|
||||
this.label = tag.getBoolean("label_visible", true) ? tag.get("label") : null;
|
||||
this.initial = tag.getString("initial", "");
|
||||
this.maxLength = tag.getInt("max_length", 32);
|
||||
if (this.maxLength < 1) {
|
||||
throw new IllegalArgumentException("Max length must be at least 1, got: " + this.maxLength);
|
||||
}
|
||||
final ListTag<CompoundTag> multilineList = tag.getListTag("multiline", CompoundTag.class);
|
||||
if (multilineList != null && !multilineList.isEmpty()) {
|
||||
this.options = multilineList.stream().map(MultilineOptions::new).toArray(MultilineOptions[]::new);
|
||||
} else {
|
||||
this.options = null;
|
||||
}
|
||||
|
||||
this.value = initial;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String key() {
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String asCommandSubstitution() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag asTag() {
|
||||
return new StringTag(value);
|
||||
}
|
||||
|
||||
public @Nullable Tag label() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public String initial() {
|
||||
return initial;
|
||||
}
|
||||
|
||||
public int maxLength() {
|
||||
return maxLength;
|
||||
}
|
||||
|
||||
public @Nullable MultilineOptions[] options() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public String value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(final String value) {
|
||||
if (value.length() > maxLength) {
|
||||
throw new IllegalArgumentException("Value exceeds max length of " + maxLength + ": " + value);
|
||||
}
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void setClampedValue(final String value) {
|
||||
if (value.length() > maxLength) {
|
||||
this.value = value.substring(0, maxLength);
|
||||
} else {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MultilineOptions {
|
||||
|
||||
private final @Nullable Integer maxLines;
|
||||
|
||||
public MultilineOptions(final CompoundTag tag) {
|
||||
final IntTag maxLinesTag = tag.getIntTag("max_lines");
|
||||
if (maxLinesTag != null && maxLinesTag.asInt() < 1) {
|
||||
throw new IllegalArgumentException("Max lines must be at least 1, got: " + maxLinesTag);
|
||||
}
|
||||
this.maxLines = maxLinesTag != null ? maxLinesTag.asInt() : null;
|
||||
}
|
||||
|
||||
public @Nullable Integer maxLines() {
|
||||
return maxLines;
|
||||
}
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.widget;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public final class ItemWidget implements Widget {
|
||||
|
||||
private final CompoundTag item;
|
||||
private final @Nullable TextWidget description;
|
||||
private final boolean showTooltip;
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
||||
public ItemWidget(final CompoundTag tag) {
|
||||
this.item = tag.getCompoundTag("item");
|
||||
if (this.item == null) {
|
||||
throw new IllegalArgumentException("Item tag is missing in ItemWidget tag: " + tag);
|
||||
}
|
||||
this.description = tag.contains("description") ? new TextWidget(tag.getCompoundTag("description")) : null;
|
||||
this.showTooltip = tag.getBoolean("show_tooltip", true);
|
||||
final int width = tag.getInt("width", 16);
|
||||
final int height = tag.getInt("height", 16);
|
||||
if (width < 1 || width > 256) {
|
||||
throw new IllegalArgumentException("Width must be between 1 and 256, got: " + width);
|
||||
}
|
||||
if (height < 1 || height > 256) {
|
||||
throw new IllegalArgumentException("Height must be between 1 and 256, got: " + height);
|
||||
}
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public CompoundTag item() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public @Nullable TextWidget description() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public boolean showTooltip() {
|
||||
return showTooltip;
|
||||
}
|
||||
|
||||
public int width() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int height() {
|
||||
return height;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.widget;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
|
||||
public final class TextWidget implements Widget {
|
||||
|
||||
private final Tag label;
|
||||
private final int width;
|
||||
|
||||
public TextWidget(final CompoundTag tag) {
|
||||
this.label = tag.get("contents");
|
||||
this.width = tag.getInt("width", 200);
|
||||
}
|
||||
|
||||
public Tag label() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public int width() {
|
||||
return width;
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.widget;
|
||||
|
||||
public interface Widget {
|
||||
}
|
||||
+598
@@ -0,0 +1,598 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.provider;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.Protocol1_21_6To1_21_5;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.Button;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.Dialog;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input.BooleanInput;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input.NumberRangeInput;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input.SingleOptionInput;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input.TextInput;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.widget.ItemWidget;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.widget.TextWidget;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.widget.Widget;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ChestDialogStorage;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ClickEvents;
|
||||
import com.viaversion.viabackwards.utils.ChatUtil;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.minecraft.item.StructuredItem;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.TooltipDisplay;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.packet.State;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.IntSortedSets;
|
||||
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.packet.ClientboundPackets1_21_5;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPackets1_21_6;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.MathUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import static com.viaversion.viabackwards.utils.ChatUtil.fixStyle;
|
||||
import static com.viaversion.viabackwards.utils.ChatUtil.text;
|
||||
import static com.viaversion.viabackwards.utils.ChatUtil.translate;
|
||||
|
||||
/**
|
||||
* Default dialog view emulator. The layout has been stretched into a lot sub-functions for plugins to override.
|
||||
*/
|
||||
public class ChestDialogViewProvider implements DialogViewProvider {
|
||||
|
||||
private static final int INVENTORY_SIZE = 27;
|
||||
private static final int INVENTORY_LAST_ROW = INVENTORY_SIZE - 9;
|
||||
|
||||
private final Protocol1_21_6To1_21_5 protocol;
|
||||
|
||||
public ChestDialogViewProvider(final Protocol1_21_6To1_21_5 protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openDialog(final UserConnection connection, final Dialog dialog) {
|
||||
final State state = connection.getProtocolInfo().getClientState();
|
||||
if (state == State.CONFIGURATION) {
|
||||
// TODO Implement by ending and re-starting the configuration phase
|
||||
return;
|
||||
}
|
||||
|
||||
// Batch text widgets following one another into a single MultiTextWidget to be display properly.
|
||||
final List<Tag> texts = new ArrayList<>();
|
||||
for (final Widget widget : new ArrayList<>(dialog.widgets())) {
|
||||
if (widget instanceof final TextWidget textWidget) {
|
||||
texts.add(textWidget.label());
|
||||
dialog.widgets().remove(textWidget);
|
||||
} else if (!texts.isEmpty()) {
|
||||
dialog.widgets().add(dialog.widgets().indexOf(widget), new MultiTextWidget(texts.toArray(Tag[]::new)));
|
||||
texts.clear();
|
||||
}
|
||||
}
|
||||
|
||||
final ChestDialogStorage previousStorage = connection.get(ChestDialogStorage.class);
|
||||
final ChestDialogStorage storage = new ChestDialogStorage(this, dialog);
|
||||
if (previousStorage != null) {
|
||||
storage.setPreviousDialog(previousStorage.dialog());
|
||||
}
|
||||
connection.put(storage);
|
||||
|
||||
openChestView(connection, storage, ChestDialogStorage.Phase.DIALOG_VIEW);
|
||||
}
|
||||
|
||||
public void openChestView(final UserConnection connection, final ChestDialogStorage storage, ChestDialogStorage.Phase phase) {
|
||||
storage.setPhase(connection, phase);
|
||||
|
||||
final PacketWrapper openScreen = PacketWrapper.create(ClientboundPackets1_21_5.OPEN_SCREEN, connection);
|
||||
openScreen.write(Types.VAR_INT, storage.containerId());
|
||||
openScreen.write(Types.VAR_INT, 2); // Container type id
|
||||
openScreen.write(Types.TAG, storage.dialog().title());
|
||||
openScreen.send(Protocol1_21_6To1_21_5.class);
|
||||
updateDialog(connection, storage.dialog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeDialog(final UserConnection connection) {
|
||||
final State state = connection.getProtocolInfo().getClientState();
|
||||
if (state == State.CONFIGURATION) {
|
||||
// TODO Implement by ending and re-starting the configuration phase
|
||||
return;
|
||||
}
|
||||
|
||||
final ChestDialogStorage storage = connection.get(ChestDialogStorage.class);
|
||||
|
||||
final PacketWrapper containerClose = PacketWrapper.create(ClientboundPackets1_21_5.CONTAINER_CLOSE, connection);
|
||||
containerClose.write(Types.VAR_INT, storage.containerId());
|
||||
containerClose.send(Protocol1_21_6To1_21_5.class);
|
||||
if (storage.previousDialog() != null) {
|
||||
openDialog(connection, storage.previousDialog());
|
||||
} else {
|
||||
connection.remove(ChestDialogStorage.class);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean clickDialog(final UserConnection connection, final int container, int slot, final byte mouse, final int mode) {
|
||||
final ChestDialogStorage storage = connection.get(ChestDialogStorage.class);
|
||||
if (storage == null || storage.containerId() != container) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mode != 0 || slot < 0 || slot >= INVENTORY_SIZE) {
|
||||
updateDialog(connection, storage.dialog()); // Resync inventory view
|
||||
return true;
|
||||
}
|
||||
|
||||
if (storage.phase() == ChestDialogStorage.Phase.ANVIL_VIEW) {
|
||||
openChestView(connection, storage, ChestDialogStorage.Phase.DIALOG_VIEW);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (storage.phase() == ChestDialogStorage.Phase.WAITING_FOR_RESPONSE) {
|
||||
if (slot == storage.actionIndex() && storage.closeButtonEnabled()) {
|
||||
closeDialog(connection);
|
||||
} else {
|
||||
updateDialog(connection, storage.dialog()); // Resync inventory view
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Page navigation
|
||||
if (slot == INVENTORY_SIZE - 1) {
|
||||
final int pages = MathUtil.ceil(storage.items().length / (float) INVENTORY_LAST_ROW);
|
||||
if (mouse == 0) {
|
||||
storage.page++;
|
||||
} else if (mouse == 1) {
|
||||
storage.page--;
|
||||
}
|
||||
storage.page = MathUtil.clamp(storage.page, 0, pages - 1);
|
||||
}
|
||||
slot += storage.page * INVENTORY_LAST_ROW;
|
||||
|
||||
// Input widgets
|
||||
final List<Widget> widgets = storage.dialog().widgets();
|
||||
if (slot < widgets.size()) {
|
||||
final Widget widget = widgets.get(slot);
|
||||
if (widget instanceof final BooleanInput booleanInput) {
|
||||
clickBooleanInput(booleanInput);
|
||||
} else if (widget instanceof final NumberRangeInput numberRangeInput) {
|
||||
clickNumberRangeInput(numberRangeInput, mouse);
|
||||
} else if (widget instanceof final TextInput textInput) {
|
||||
clickTextInput(connection, textInput);
|
||||
} else if (widget instanceof final SingleOptionInput singleOptionInput) {
|
||||
clickSingleOptionInput(singleOptionInput);
|
||||
} else if (widget instanceof final Button button) {
|
||||
clickButton(connection, storage.dialog().afterAction(), button);
|
||||
} else if (widget instanceof final Dialog dialog) {
|
||||
clickDialogButton(connection, dialog);
|
||||
}
|
||||
}
|
||||
|
||||
// And some special cases.
|
||||
if (slot == storage.confirmationYesIndex()) {
|
||||
final Button yesButton = storage.dialog().yesButton();
|
||||
if (yesButton != null) {
|
||||
clickButton(connection, storage.dialog().afterAction(), yesButton);
|
||||
}
|
||||
}
|
||||
if (slot == storage.confirmationNoIndex()) {
|
||||
final Button noButton = storage.dialog().noButton();
|
||||
if (noButton != null) {
|
||||
clickButton(connection, storage.dialog().afterAction(), noButton);
|
||||
}
|
||||
}
|
||||
if (slot == storage.actionIndex()) {
|
||||
final Button actionButton = storage.dialog().actionButton();
|
||||
if (actionButton != null) {
|
||||
clickButton(connection, storage.dialog().afterAction(), actionButton);
|
||||
}
|
||||
}
|
||||
|
||||
// Resync inventory view if the actions above didn't close the dialog.
|
||||
if (connection.has(ChestDialogStorage.class) && storage.phase() == ChestDialogStorage.Phase.DIALOG_VIEW) {
|
||||
updateDialog(connection, storage.dialog());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateDialog(final UserConnection connection, final Dialog dialog) {
|
||||
final ChestDialogStorage storage = connection.get(ChestDialogStorage.class);
|
||||
|
||||
final PacketWrapper containerSetContent = PacketWrapper.create(ClientboundPackets1_21_5.CONTAINER_SET_CONTENT, connection);
|
||||
containerSetContent.write(Types.VAR_INT, storage.containerId());
|
||||
containerSetContent.write(Types.VAR_INT, 0); // Revision
|
||||
containerSetContent.write(VersionedTypes.V1_21_5.itemArray, getItems(connection, storage, dialog));
|
||||
containerSetContent.write(VersionedTypes.V1_21_5.item, StructuredItem.empty());
|
||||
containerSetContent.send(Protocol1_21_6To1_21_5.class);
|
||||
}
|
||||
|
||||
protected Item createPageNavigationItem() {
|
||||
return createItem(
|
||||
"minecraft:arrow",
|
||||
text("§9§lPage navigation"),
|
||||
|
||||
"§9Left click: §6Go to next page",
|
||||
"§9Right click: §6Go to previous page"
|
||||
);
|
||||
}
|
||||
|
||||
protected Item createActionButtonItem(final UserConnection connection, final Button button) {
|
||||
final Tag label = handleTag(connection, button.label());
|
||||
if (button.tooltip() == null) {
|
||||
return createItem("minecraft:oak_button", label);
|
||||
} else {
|
||||
return createItem("minecraft:oak_button", label, handleTag(connection, button.tooltip()));
|
||||
}
|
||||
}
|
||||
|
||||
protected Item createCloseButtonItem(final Tag label) {
|
||||
return createItem("minecraft:oak_button", label);
|
||||
}
|
||||
|
||||
protected Item getItemWidget(final UserConnection connection, final ItemWidget itemWidget) {
|
||||
final String identifier = itemWidget.item().getString("id");
|
||||
final int count = itemWidget.item().getInt("count", 1);
|
||||
|
||||
final Tag label = text(Key.stripMinecraftNamespace(identifier));
|
||||
final Item item = createItem(identifier, label);
|
||||
item.setAmount(count);
|
||||
if (itemWidget.description() != null) {
|
||||
item.dataContainer().set(StructuredDataKey.LORE, new Tag[]{
|
||||
handleTag(connection, fixStyle(itemWidget.description().label()))
|
||||
});
|
||||
}
|
||||
if (!itemWidget.showTooltip()) {
|
||||
item.dataContainer().set(StructuredDataKey.TOOLTIP_DISPLAY, new TooltipDisplay(true, IntSortedSets.EMPTY_SET));
|
||||
}
|
||||
// If we were to parse item components from NBT for chat items they would be parsed here and stored into the data container.
|
||||
// In VV, chat items are rewritten manually at the time being and therefore no conversion code exists.
|
||||
return item;
|
||||
}
|
||||
|
||||
protected Item getMultiTextWidget(final UserConnection connection, final MultiTextWidget multiTextWidget) {
|
||||
final Tag name = handleTag(connection, multiTextWidget.labels()[0]);
|
||||
final int length = multiTextWidget.labels().length;
|
||||
if (length == 1) {
|
||||
return createItem("minecraft:paper", name);
|
||||
}
|
||||
|
||||
final Tag[] lore = new Tag[length - 1];
|
||||
for (int i = 1; i < length; i++) {
|
||||
lore[i - 1] = handleTag(connection, fixStyle(multiTextWidget.labels()[i]));
|
||||
}
|
||||
return createItem("minecraft:paper", name, lore);
|
||||
}
|
||||
|
||||
protected Item getBooleanInput(final UserConnection connection, final BooleanInput booleanInput) {
|
||||
final String item = booleanInput.value() ? "minecraft:lime_dye" : "minecraft:gray_dye";
|
||||
final Tag[] label = ChatUtil.split(booleanInput.label(), "\n");
|
||||
|
||||
// The only one that supports newlines in the label
|
||||
if (label.length == 1) {
|
||||
return createItem(
|
||||
item,
|
||||
handleTag(connection, booleanInput.label()),
|
||||
text("§9Left click: §6Toggle value")
|
||||
);
|
||||
} else {
|
||||
final Tag[] lore = new Tag[label.length];
|
||||
for (int i = 1; i < label.length; i++) {
|
||||
lore[i - 1] = handleTag(connection, fixStyle(label[i]));
|
||||
}
|
||||
lore[lore.length - 1] = text("§9Left click: §6Toggle value");
|
||||
return createItem(
|
||||
item,
|
||||
handleTag(connection, label[0]),
|
||||
lore
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected void clickBooleanInput(final BooleanInput booleanInput) {
|
||||
booleanInput.setValue(!booleanInput.value());
|
||||
}
|
||||
|
||||
protected Item getNumberRangeInput(final UserConnection connection, final NumberRangeInput numberRangeInput) {
|
||||
final Tag label = handleTag(connection, numberRangeInput.displayName());
|
||||
return createItem(
|
||||
"minecraft:clock",
|
||||
label,
|
||||
|
||||
"§9Left click: §6Increase value by " + numberRangeInput.step(),
|
||||
"§9Right click: §6Decrease value by " + numberRangeInput.step(),
|
||||
"§7(Value between §a" + numberRangeInput.start() + " §7and §a" + numberRangeInput.end() + "§7)"
|
||||
);
|
||||
}
|
||||
|
||||
protected void clickNumberRangeInput(final NumberRangeInput numberRangeInput, final int mouse) {
|
||||
float value = numberRangeInput.value();
|
||||
if (mouse == 0) { // Left click
|
||||
value += numberRangeInput.step();
|
||||
} else if (mouse == 1) { // Right click
|
||||
value -= numberRangeInput.step();
|
||||
}
|
||||
numberRangeInput.setClampedValue(value);
|
||||
}
|
||||
|
||||
protected Item getTextInput(final UserConnection connection, final TextInput textInput) {
|
||||
final Tag currentValue = text("§7Current value: §a" + textInput.value());
|
||||
if (textInput.label() == null) {
|
||||
return createItem("minecraft:writable_book", currentValue);
|
||||
} else {
|
||||
final Tag label = handleTag(connection, textInput.label());
|
||||
return createItem("minecraft:writable_book", label, currentValue, text("§9Left click: §6Edit text"));
|
||||
}
|
||||
}
|
||||
|
||||
protected void clickTextInput(final UserConnection connection, final TextInput textInput) {
|
||||
final ChestDialogStorage storage = connection.get(ChestDialogStorage.class);
|
||||
openAnvilView(connection, storage, text("§7Edit text"), textInput.value(), textInput);
|
||||
}
|
||||
|
||||
protected Item getSingleOptionInput(final UserConnection connection, final SingleOptionInput singleOptionInput) {
|
||||
final Tag displayName = singleOptionInput.options()[singleOptionInput.value()].computeDisplay();
|
||||
final Tag label;
|
||||
if (singleOptionInput.label() != null) {
|
||||
label = translate("options.generic_value", singleOptionInput.label(), displayName);
|
||||
} else {
|
||||
label = displayName;
|
||||
}
|
||||
return createItem(
|
||||
"minecraft:bookshelf",
|
||||
handleTag(connection, label),
|
||||
"§9Left click: §6Go to next option",
|
||||
"§9Right click: §6Go to previous option"
|
||||
);
|
||||
}
|
||||
|
||||
protected void clickSingleOptionInput(final SingleOptionInput singleOptionInput) {
|
||||
singleOptionInput.setClampedValue(singleOptionInput.value() + 1);
|
||||
}
|
||||
|
||||
protected Item getButton(final UserConnection connection, final Button button) {
|
||||
return createItem("minecraft:oak_button", handleTag(connection, button.label()));
|
||||
}
|
||||
|
||||
public void clickButton(final UserConnection connection, final Dialog.AfterAction afterAction, @Nullable final Button button) {
|
||||
final ChestDialogStorage storage = connection.get(ChestDialogStorage.class);
|
||||
switch (afterAction) {
|
||||
case CLOSE -> closeDialog(connection);
|
||||
case WAIT_FOR_RESPONSE -> storage.setPhase(null, ChestDialogStorage.Phase.WAITING_FOR_RESPONSE);
|
||||
}
|
||||
|
||||
if (button == null || button.clickEvent() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final CompoundTag clickEvent = button.clickEvent();
|
||||
final String action = Key.stripMinecraftNamespace(clickEvent.getString("action"));
|
||||
switch (action) {
|
||||
case "open_url" -> {
|
||||
// We can't open a URL for the client, so roughly emulate by opening an Anvil containing the URL.
|
||||
final String url = clickEvent.getString("url");
|
||||
openAnvilView(connection, storage, text("Open URL"), url, null);
|
||||
}
|
||||
case "run_command" -> {
|
||||
// The vanilla client validates for signed argument types and has more requirements for this click event,
|
||||
// but we can't do this here and therefore just always send the packet assuming this is correct...
|
||||
final PacketWrapper chatCommand = PacketWrapper.create(ServerboundPackets1_21_6.CHAT_COMMAND, connection);
|
||||
String command = clickEvent.getString("command");
|
||||
if (command.startsWith("/")) {
|
||||
command = command.substring(1);
|
||||
}
|
||||
chatCommand.write(Types.STRING, command);
|
||||
chatCommand.sendToServer(Protocol1_21_6To1_21_5.class);
|
||||
}
|
||||
case "copy_to_clipboard" -> {
|
||||
// Same as above, we can't access the clipboard
|
||||
final String value = clickEvent.getString("value");
|
||||
openAnvilView(connection, storage, text("Copy to clipboard"), value, null);
|
||||
}
|
||||
}
|
||||
|
||||
ClickEvents.handleClickEvent(connection, clickEvent); // Handle show_dialog and custom
|
||||
}
|
||||
|
||||
protected Item createTextInputItem(final String value) {
|
||||
return createItem("minecraft:paper", text(value), "§9Left click/close: §6Set text");
|
||||
}
|
||||
|
||||
protected Item createTextCopyItem(final String value) {
|
||||
return createItem("minecraft:paper", text(value), "§9Left click: §6Close");
|
||||
}
|
||||
|
||||
private void openAnvilView(
|
||||
final UserConnection connection,
|
||||
final ChestDialogStorage storage,
|
||||
final Tag title,
|
||||
final String value,
|
||||
final TextInput textInput
|
||||
) {
|
||||
storage.setPhase(connection, ChestDialogStorage.Phase.ANVIL_VIEW);
|
||||
|
||||
final PacketWrapper openScreen = PacketWrapper.create(ClientboundPackets1_21_5.OPEN_SCREEN, connection);
|
||||
openScreen.write(Types.VAR_INT, storage.containerId());
|
||||
openScreen.write(Types.VAR_INT, 8); // Container type id
|
||||
openScreen.write(Types.TAG, title);
|
||||
openScreen.send(Protocol1_21_6To1_21_5.class);
|
||||
|
||||
final Item[] items = new Item[1];
|
||||
items[0] = textInput != null ? createTextInputItem(value) : createTextCopyItem(value);
|
||||
storage.setCurrentTextInput(textInput);
|
||||
|
||||
final PacketWrapper containerSetContent = PacketWrapper.create(ClientboundPackets1_21_5.CONTAINER_SET_CONTENT, connection);
|
||||
containerSetContent.write(Types.VAR_INT, storage.containerId());
|
||||
containerSetContent.write(Types.VAR_INT, 0); // Revision
|
||||
containerSetContent.write(VersionedTypes.V1_21_5.itemArray, items);
|
||||
containerSetContent.write(VersionedTypes.V1_21_5.item, StructuredItem.empty());
|
||||
containerSetContent.send(Protocol1_21_6To1_21_5.class);
|
||||
}
|
||||
|
||||
public void updateAnvilText(final UserConnection connection, final String value) {
|
||||
if (value.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ChestDialogStorage storage = connection.get(ChestDialogStorage.class);
|
||||
if (storage.currentTextInput() != null) {
|
||||
storage.currentTextInput().setClampedValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
protected Item getDialog(final UserConnection connection, final Dialog dialog) {
|
||||
final Tag title = dialog.externalTitle() != null ? dialog.externalTitle() : dialog.title();
|
||||
return createItem("minecraft:command_block", handleTag(connection, title));
|
||||
}
|
||||
|
||||
protected void clickDialogButton(final UserConnection connection, final Dialog dialog) {
|
||||
closeDialog(connection);
|
||||
openDialog(connection, dialog);
|
||||
}
|
||||
|
||||
protected Item getItem(final UserConnection connection, final Widget widget) {
|
||||
if (widget instanceof final ItemWidget itemWidget) {
|
||||
return getItemWidget(connection, itemWidget);
|
||||
} else if (widget instanceof final MultiTextWidget multiTextWidget) {
|
||||
return getMultiTextWidget(connection, multiTextWidget);
|
||||
} else if (widget instanceof final BooleanInput booleanInput) {
|
||||
return getBooleanInput(connection, booleanInput);
|
||||
} else if (widget instanceof final NumberRangeInput numberRangeInput) {
|
||||
return getNumberRangeInput(connection, numberRangeInput);
|
||||
} else if (widget instanceof TextInput textInput) {
|
||||
return getTextInput(connection, textInput);
|
||||
} else if (widget instanceof SingleOptionInput singleOptionInput) {
|
||||
return getSingleOptionInput(connection, singleOptionInput);
|
||||
} else if (widget instanceof Button button) {
|
||||
return getButton(connection, button);
|
||||
} else if (widget instanceof Dialog dialog) {
|
||||
return getDialog(connection, dialog);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown widget type: " + widget.getClass().getName());
|
||||
}
|
||||
|
||||
protected Item[] getItems(final UserConnection connection, final ChestDialogStorage storage, final Dialog dialog) {
|
||||
final Item[] items = StructuredItem.emptyArray(INVENTORY_SIZE);
|
||||
int confirmationYesIndex = -1;
|
||||
int confirmationNoIndex = -1;
|
||||
int actionIndex = -1;
|
||||
|
||||
if (storage.phase() == ChestDialogStorage.Phase.WAITING_FOR_RESPONSE) {
|
||||
actionIndex = 13;
|
||||
|
||||
items[actionIndex] = createCloseButtonItem(storage.closeButtonLabel());
|
||||
storage.setItems(items, confirmationYesIndex, confirmationNoIndex, actionIndex);
|
||||
return items;
|
||||
}
|
||||
|
||||
final List<Widget> widgets = dialog.widgets();
|
||||
if (widgets.size() > INVENTORY_LAST_ROW) {
|
||||
final int begin = storage.page * INVENTORY_LAST_ROW;
|
||||
final int end = Math.min((storage.page + 1) * INVENTORY_LAST_ROW, widgets.size());
|
||||
for (int i = 0; i < end - begin; i++) {
|
||||
items[i] = getItem(connection, widgets.get(begin + i));
|
||||
}
|
||||
|
||||
items[INVENTORY_SIZE - 1] = createPageNavigationItem();
|
||||
} else {
|
||||
for (int i = 0; i < widgets.size(); i++) {
|
||||
items[i] = getItem(connection, widgets.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
// And some special cases.
|
||||
if (dialog.yesButton() != null && dialog.noButton() != null) {
|
||||
confirmationYesIndex = widgets.isEmpty() ? 11 : INVENTORY_SIZE - 7;
|
||||
confirmationNoIndex = widgets.isEmpty() ? 15 : INVENTORY_SIZE - 3;
|
||||
|
||||
items[confirmationYesIndex] = createActionButtonItem(connection, dialog.yesButton());
|
||||
items[confirmationNoIndex] = createActionButtonItem(connection, dialog.noButton());
|
||||
}
|
||||
if (dialog.actionButton() != null) {
|
||||
actionIndex = widgets.isEmpty() ? 13 : INVENTORY_SIZE - 9;
|
||||
|
||||
items[actionIndex] = createActionButtonItem(connection, dialog.actionButton());
|
||||
}
|
||||
|
||||
storage.setItems(items, confirmationYesIndex, confirmationNoIndex, actionIndex);
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the 1.21.6 tag inside the Dialog structure and rewrites it to the 1.21.5 format. This is necessary
|
||||
* for replacing translations used by Dialogs which only exist in 1.21.6+. Call this function for every text component
|
||||
* you display from the server.
|
||||
*
|
||||
* @param connection the user connection
|
||||
* @param tag the text component as a tag, or null if no tag is present
|
||||
* @return the rewritten tag, or null if the input tag was null
|
||||
*/
|
||||
private @Nullable Tag handleTag(final UserConnection connection, final @Nullable Tag tag) {
|
||||
if (tag == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
protocol.getComponentRewriter().processTag(connection, tag);
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* This doesn't actually exist in Minecraft but is created if multiple {@link TextWidget} follow one another in order
|
||||
* to improve readability in chest inventories.
|
||||
*/
|
||||
public record MultiTextWidget(Tag[] labels) implements Widget {
|
||||
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------------
|
||||
|
||||
protected Item createItem(final String identifier, final Tag name) {
|
||||
return createItem(identifier, name, new String[0]);
|
||||
}
|
||||
|
||||
protected Item createItem(final String identifier, final Tag name, final Tag... description) {
|
||||
final int id = protocol.getMappingData().getFullItemMappings().mappedId(identifier);
|
||||
|
||||
final StructuredDataContainer data = new StructuredDataContainer();
|
||||
data.setIdLookup(protocol, true);
|
||||
data.set(StructuredDataKey.ITEM_NAME, name);
|
||||
if (description != null) {
|
||||
data.set(StructuredDataKey.LORE, description);
|
||||
}
|
||||
return new StructuredItem(id, 1, data);
|
||||
}
|
||||
|
||||
protected Item createItem(final String identifier, final Tag name, final String... description) {
|
||||
final int id = protocol.getMappingData().getFullItemMappings().mappedId(identifier);
|
||||
|
||||
final StructuredDataContainer data = new StructuredDataContainer();
|
||||
data.setIdLookup(protocol, true);
|
||||
data.set(StructuredDataKey.ITEM_NAME, name);
|
||||
if (description.length > 0) {
|
||||
final List<Tag> lore = new ArrayList<>();
|
||||
for (final String s : description) {
|
||||
lore.add(text(s));
|
||||
}
|
||||
data.set(StructuredDataKey.LORE, lore.toArray(new Tag[0]));
|
||||
}
|
||||
return new StructuredItem(id, 1, data);
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.provider;
|
||||
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.Dialog;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.platform.providers.Provider;
|
||||
|
||||
/**
|
||||
* Interface for providing dialog view functionality to this protocol. Requires a storage
|
||||
* to save per-user data while being able to have open and close logic static.
|
||||
* <p>
|
||||
* See {@link Dialog} for the structure of a dialog.
|
||||
* <p>
|
||||
* See {@link ChestDialogViewProvider} for the protocol level emulation using a chest.
|
||||
*/
|
||||
public interface DialogViewProvider extends Provider {
|
||||
|
||||
void openDialog(final UserConnection connection, final Dialog dialog);
|
||||
|
||||
void closeDialog(final UserConnection connection);
|
||||
|
||||
}
|
||||
+4
-4
@@ -142,10 +142,10 @@ public final class BlockItemPacketRewriter1_21_6 extends BackwardsStructuredItem
|
||||
final CompoundTag equippableTag = backupTag.getCompoundTag("equippable");
|
||||
if (equippableTag != null) {
|
||||
container.replace(StructuredDataKey.EQUIPPABLE1_21_5, StructuredDataKey.EQUIPPABLE1_21_6, equippable -> new Equippable(
|
||||
equippable.equipmentSlot(), equippable.soundEvent(), equippable.model(), equippable.cameraOverlay(), equippable.allowedEntities(),
|
||||
equippable.dispensable(), equippable.swappable(), equippable.damageOnHurt(), equippable.equipOnInteract(),
|
||||
equippableTag.getBoolean("can_be_sheared"),
|
||||
restoreSoundEventHolder(equippableTag)
|
||||
equippable.equipmentSlot(), equippable.soundEvent(), equippable.model(), equippable.cameraOverlay(), equippable.allowedEntities(),
|
||||
equippable.dispensable(), equippable.swappable(), equippable.damageOnHurt(), equippable.equipOnInteract(),
|
||||
equippableTag.getBoolean("can_be_sheared"),
|
||||
restoreSoundEventHolder(equippableTag)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
+28
-2
@@ -20,6 +20,8 @@ package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.rewriter;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viabackwards.api.rewriters.text.NBTComponentRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ChestDialogStorage;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ClickEvents;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPacket1_21_6;
|
||||
|
||||
@@ -39,8 +41,32 @@ public final class ComponentRewriter1_21_6 extends NBTComponentRewriter<Clientbo
|
||||
}
|
||||
|
||||
final String action = clickEvent.getString("action");
|
||||
if ("custom".equals(action)) {
|
||||
tag.remove("click_event");
|
||||
|
||||
final ChestDialogStorage chestDialogStorage = connection.get(ChestDialogStorage.class);
|
||||
if (chestDialogStorage != null) {
|
||||
// Short way out - remove when in dialog, buttons are handled separately
|
||||
if ("show_dialog".equals(action) || "custom".equals(action)) {
|
||||
tag.remove("click_event");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Make them run a command generated by us executing the actual logic
|
||||
if ("show_dialog".equals(action)) {
|
||||
final ClickEvents clickEvents = connection.get(ClickEvents.class);
|
||||
final String command = clickEvents.storeClickEvent(clickEvent.copy());
|
||||
|
||||
clickEvent.putString("action", "run_command");
|
||||
clickEvent.putString("command", command);
|
||||
clickEvent.remove("dialog");
|
||||
} else if ("custom".equals(action)) {
|
||||
final ClickEvents clickEvents = connection.get(ClickEvents.class);
|
||||
final String command = clickEvents.storeClickEvent(clickEvent.copy());
|
||||
|
||||
clickEvent.putString("action", "run_command");
|
||||
clickEvent.putString("command", command);
|
||||
clickEvent.remove("id");
|
||||
clickEvent.remove("payload");
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
-3
@@ -17,19 +17,29 @@
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viabackwards.api.rewriters.BackwardsRegistryRewriter;
|
||||
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.Protocol1_21_6To1_21_5;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.RegistryAndTags;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_6;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21_5;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectArrayMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectMap;
|
||||
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.packet.ClientboundPackets1_21_5;
|
||||
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.packet.ServerboundPackets1_21_5;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundConfigurationPackets1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPacket1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPackets1_21_6;
|
||||
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.KeyMappings;
|
||||
|
||||
public final class EntityPacketRewriter1_21_6 extends EntityRewriter<ClientboundPacket1_21_6, Protocol1_21_6To1_21_5> {
|
||||
|
||||
@@ -39,7 +49,6 @@ public final class EntityPacketRewriter1_21_6 extends EntityRewriter<Clientbound
|
||||
|
||||
@Override
|
||||
public void registerPackets() {
|
||||
registerTrackerWithData1_19(ClientboundPackets1_21_6.ADD_ENTITY, EntityTypes1_21_6.FALLING_BLOCK);
|
||||
registerSetEntityData(ClientboundPackets1_21_6.SET_ENTITY_DATA);
|
||||
registerRemoveEntities(ClientboundPackets1_21_6.REMOVE_ENTITIES);
|
||||
registerPlayerAbilities(ClientboundPackets1_21_6.PLAYER_ABILITIES);
|
||||
@@ -47,8 +56,59 @@ public final class EntityPacketRewriter1_21_6 extends EntityRewriter<Clientbound
|
||||
registerLogin1_20_5(ClientboundPackets1_21_6.LOGIN);
|
||||
registerRespawn1_20_5(ClientboundPackets1_21_6.RESPAWN);
|
||||
|
||||
final RegistryDataRewriter registryDataRewriter = new BackwardsRegistryRewriter(protocol);
|
||||
registryDataRewriter.remove("dialog");
|
||||
protocol.appendClientbound(ClientboundPackets1_21_6.ADD_ENTITY, wrapper -> {
|
||||
final int entityId = wrapper.passthrough(Types.VAR_INT);
|
||||
wrapper.passthrough(Types.UUID); // Entity UUID
|
||||
final int entityType = wrapper.passthrough(Types.VAR_INT);
|
||||
wrapper.passthrough(Types.DOUBLE); // X
|
||||
wrapper.passthrough(Types.DOUBLE); // Y
|
||||
wrapper.passthrough(Types.DOUBLE); // Z
|
||||
wrapper.passthrough(Types.BYTE); // Pitch
|
||||
wrapper.passthrough(Types.BYTE); // Yaw
|
||||
wrapper.passthrough(Types.BYTE); // Head yaw
|
||||
wrapper.passthrough(Types.VAR_INT); // Data
|
||||
final short velocityX = wrapper.passthrough(Types.SHORT);
|
||||
final short velocityY = wrapper.passthrough(Types.SHORT);
|
||||
final short velocityZ = wrapper.passthrough(Types.SHORT);
|
||||
getSpawnTrackerWithDataHandler1_19(EntityTypes1_21_6.FALLING_BLOCK).handle(wrapper);
|
||||
if (velocityX != 0 || velocityY != 0 || velocityZ != 0) {
|
||||
if (!typeFromId(entityType).isOrHasParent(EntityTypes1_21_6.LIVING_ENTITY)) {
|
||||
// Send movement separately
|
||||
final PacketWrapper motionPacket = wrapper.create(ClientboundPackets1_21_5.SET_ENTITY_MOTION);
|
||||
motionPacket.write(Types.VAR_INT, entityId);
|
||||
motionPacket.write(Types.SHORT, velocityX);
|
||||
motionPacket.write(Types.SHORT, velocityY);
|
||||
motionPacket.write(Types.SHORT, velocityZ);
|
||||
wrapper.send(Protocol1_21_6To1_21_5.class);
|
||||
motionPacket.send(Protocol1_21_6To1_21_5.class);
|
||||
wrapper.cancel();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
final RegistryDataRewriter registryDataRewriter = new BackwardsRegistryRewriter(protocol) {
|
||||
@Override
|
||||
public RegistryEntry[] handle(final UserConnection connection, final String key, final RegistryEntry[] entries) {
|
||||
if (Key.stripMinecraftNamespace(key).equals("dialog")) {
|
||||
final String[] keys = new String[entries.length];
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
keys[i] = Key.stripMinecraftNamespace(entries[i].key());
|
||||
}
|
||||
|
||||
final Object2ObjectMap<String, CompoundTag> dialogs = new Object2ObjectArrayMap<>();
|
||||
for (final RegistryEntry entry : entries) {
|
||||
if (entry.tag() instanceof final CompoundTag tag) {
|
||||
dialogs.put(Key.stripMinecraftNamespace(entry.key()), tag);
|
||||
}
|
||||
}
|
||||
|
||||
final RegistryAndTags registryAndTags = connection.get(RegistryAndTags.class);
|
||||
registryAndTags.storeRegistry(new KeyMappings(keys), dialogs);
|
||||
}
|
||||
return super.handle(connection, key, entries);
|
||||
}
|
||||
};
|
||||
registryDataRewriter.remove("dialog"); // Tracked and now removed
|
||||
protocol.registerClientbound(ClientboundConfigurationPackets1_21_6.REGISTRY_DATA, registryDataRewriter::handle);
|
||||
|
||||
protocol.registerServerbound(ServerboundPackets1_21_5.PLAYER_COMMAND, wrapper -> {
|
||||
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage;
|
||||
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.Protocol1_21_6To1_21_5;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.Dialog;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.input.TextInput;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.provider.ChestDialogViewProvider;
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.packet.ClientboundPackets1_21_5;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import static com.viaversion.viabackwards.utils.ChatUtil.text;
|
||||
import static com.viaversion.viabackwards.utils.ChatUtil.translate;
|
||||
|
||||
/**
|
||||
* Per-user storage for {@link ChestDialogViewProvider}
|
||||
*/
|
||||
public final class ChestDialogStorage implements StorableObject {
|
||||
|
||||
private static final byte MIN_FAKE_ID = Byte.MAX_VALUE / 2 + 1;
|
||||
private static final byte MAX_FAKE_ID = Byte.MAX_VALUE - 1;
|
||||
private static final AtomicInteger FAKE_ID_COUNTER = new AtomicInteger(MIN_FAKE_ID);
|
||||
|
||||
private static final Tag[] RESPONSE_BUTTON_LABELS = new Tag[]{
|
||||
text(""),
|
||||
translate("gui.waitingForResponse.button.inactive", 4),
|
||||
translate("gui.waitingForResponse.button.inactive", 3),
|
||||
translate("gui.waitingForResponse.button.inactive", 2),
|
||||
translate("gui.waitingForResponse.button.inactive", 1),
|
||||
translate("gui.back")
|
||||
};
|
||||
|
||||
private final ChestDialogViewProvider provider;
|
||||
private final Dialog dialog;
|
||||
private int containerId;
|
||||
private Dialog previousDialog;
|
||||
|
||||
public int page;
|
||||
|
||||
private Item[] items;
|
||||
private int confirmationYesIndex = -1;
|
||||
private int confirmationNoIndex = -1;
|
||||
|
||||
private int actionIndex = -1;
|
||||
|
||||
private @Nullable Phase phase;
|
||||
|
||||
private int ticksWaitingForResponse = 0;
|
||||
|
||||
private boolean closeButtonEnabled;
|
||||
private Tag closeButtonLabel;
|
||||
|
||||
private TextInput currentTextInput;
|
||||
|
||||
private boolean allowClosing;
|
||||
|
||||
public ChestDialogStorage(final ChestDialogViewProvider provider, final Dialog dialog) {
|
||||
this.provider = provider;
|
||||
this.dialog = dialog;
|
||||
}
|
||||
|
||||
public void tick(final UserConnection connection) {
|
||||
if (phase != Phase.WAITING_FOR_RESPONSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int index = ticksWaitingForResponse++ / 20;
|
||||
if (index > RESPONSE_BUTTON_LABELS.length - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
closeButtonEnabled = index >= 1;
|
||||
closeButtonLabel = RESPONSE_BUTTON_LABELS[index];
|
||||
provider.updateDialog(connection, dialog);
|
||||
}
|
||||
|
||||
public Dialog dialog() {
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public @Nullable Dialog previousDialog() {
|
||||
return previousDialog;
|
||||
}
|
||||
|
||||
public void setPreviousDialog(final Dialog previousDialog) {
|
||||
this.previousDialog = previousDialog;
|
||||
}
|
||||
|
||||
public int containerId() {
|
||||
return containerId;
|
||||
}
|
||||
|
||||
public Item[] items() {
|
||||
return items;
|
||||
}
|
||||
|
||||
public void setItems(final Item[] items, final int confirmationYesIndex, final int confirmationNoIndex, final int actionIndex) {
|
||||
this.items = items;
|
||||
this.confirmationYesIndex = confirmationYesIndex;
|
||||
this.confirmationNoIndex = confirmationNoIndex;
|
||||
this.actionIndex = actionIndex;
|
||||
}
|
||||
|
||||
public int confirmationYesIndex() {
|
||||
return confirmationYesIndex;
|
||||
}
|
||||
|
||||
public int confirmationNoIndex() {
|
||||
return confirmationNoIndex;
|
||||
}
|
||||
|
||||
public int actionIndex() {
|
||||
return actionIndex;
|
||||
}
|
||||
|
||||
public @Nullable Phase phase() {
|
||||
return phase;
|
||||
}
|
||||
|
||||
public boolean closeButtonEnabled() {
|
||||
return closeButtonEnabled;
|
||||
}
|
||||
|
||||
public Tag closeButtonLabel() {
|
||||
return closeButtonLabel;
|
||||
}
|
||||
|
||||
public TextInput currentTextInput() {
|
||||
return currentTextInput;
|
||||
}
|
||||
|
||||
public boolean allowClosing() {
|
||||
return allowClosing;
|
||||
}
|
||||
|
||||
public void setPhase(final UserConnection connection, final @Nullable Phase phase) {
|
||||
if (phase == Phase.DIALOG_VIEW || phase == Phase.ANVIL_VIEW) {
|
||||
if (this.phase != null) {
|
||||
final PacketWrapper containerClose = PacketWrapper.create(ClientboundPackets1_21_5.CONTAINER_CLOSE, connection);
|
||||
containerClose.write(Types.VAR_INT, containerId);
|
||||
containerClose.send(Protocol1_21_6To1_21_5.class);
|
||||
}
|
||||
currentTextInput = null;
|
||||
|
||||
final int id = FAKE_ID_COUNTER.getAndIncrement();
|
||||
if (id > MAX_FAKE_ID) {
|
||||
FAKE_ID_COUNTER.set(MIN_FAKE_ID);
|
||||
containerId = MIN_FAKE_ID;
|
||||
} else {
|
||||
containerId = (byte) id;
|
||||
}
|
||||
}
|
||||
|
||||
this.phase = phase;
|
||||
}
|
||||
|
||||
public void setCurrentTextInput(final TextInput currentTextInput) {
|
||||
this.currentTextInput = currentTextInput;
|
||||
}
|
||||
|
||||
public void setAllowClosing(final boolean allowClosing) {
|
||||
this.allowClosing = allowClosing;
|
||||
}
|
||||
|
||||
public enum Phase {
|
||||
|
||||
DIALOG_VIEW,
|
||||
ANVIL_VIEW,
|
||||
WAITING_FOR_RESPONSE
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.Protocol1_21_6To1_21_5;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.Dialog;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.provider.DialogViewProvider;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectArrayMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectMap;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPackets1_21_6;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class ClickEvents implements StorableObject {
|
||||
|
||||
private final Object2ObjectMap<String, CompoundTag> clickEvents = new Object2ObjectArrayMap<>();
|
||||
|
||||
public String storeClickEvent(final CompoundTag clickEvent) {
|
||||
final String id = "vv_" + UUID.randomUUID();
|
||||
if (clickEvents.containsKey(id)) {
|
||||
return storeClickEvent(clickEvent); // Ensure unique ID
|
||||
}
|
||||
clickEvents.put(id, clickEvent);
|
||||
return id;
|
||||
}
|
||||
|
||||
public boolean handleChatCommand(final UserConnection connection, final String command) {
|
||||
final CompoundTag clickEvent = clickEvents.get(command);
|
||||
if (clickEvent != null) {
|
||||
handleClickEvent(connection, clickEvent);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleClickEvent(final UserConnection connection, final CompoundTag clickEvent) {
|
||||
final String action = Key.stripMinecraftNamespace(clickEvent.getString("action"));
|
||||
if ("show_dialog".equals(action)) {
|
||||
final RegistryAndTags registryAndTags = connection.get(RegistryAndTags.class);
|
||||
final ServerLinks serverLinks = connection.get(ServerLinks.class);
|
||||
|
||||
CompoundTag dialogTag = clickEvent.getCompoundTag("dialog");
|
||||
if (dialogTag == null) {
|
||||
final StringTag dialogReferenceTag = clickEvent.getStringTag("dialog");
|
||||
if (dialogReferenceTag != null) { // No tags here
|
||||
dialogTag = registryAndTags.fromRegistry(Key.stripMinecraftNamespace(dialogReferenceTag.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
final DialogViewProvider provider = Via.getManager().getProviders().get(DialogViewProvider.class);
|
||||
provider.openDialog(connection, new Dialog(registryAndTags, serverLinks, dialogTag));
|
||||
} else if ("custom".equals(action)) {
|
||||
final String id = clickEvent.getString("id");
|
||||
final CompoundTag payload = clickEvent.getCompoundTag("payload");
|
||||
|
||||
final PacketWrapper customClickAction = PacketWrapper.create(ServerboundPackets1_21_6.CUSTOM_CLICK_ACTION, connection);
|
||||
customClickAction.write(Types.STRING, id);
|
||||
customClickAction.write(Types.CUSTOM_CLICK_ACTION_TAG, payload);
|
||||
|
||||
customClickAction.sendToServer(Protocol1_21_6To1_21_5.class);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectArrayMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectMap;
|
||||
import com.viaversion.viaversion.util.Key;
|
||||
import com.viaversion.viaversion.util.KeyMappings;
|
||||
|
||||
public final class RegistryAndTags implements StorableObject {
|
||||
|
||||
private KeyMappings dialogMappings;
|
||||
private Object2ObjectMap<String, CompoundTag> dialogs;
|
||||
|
||||
private Object2ObjectMap<String, int[]> dialogTags;
|
||||
|
||||
public void storeRegistry(final KeyMappings dialogMappings, final Object2ObjectMap<String, CompoundTag> dialogs) {
|
||||
this.dialogMappings = dialogMappings;
|
||||
this.dialogs = dialogs;
|
||||
}
|
||||
|
||||
public CompoundTag fromRegistry(final int id) {
|
||||
return dialogs.get(dialogMappings.idToKey(id));
|
||||
}
|
||||
|
||||
public CompoundTag fromRegistry(final String key) {
|
||||
return dialogs.get(Key.stripMinecraftNamespace(key));
|
||||
}
|
||||
|
||||
public boolean tagsSent() {
|
||||
return dialogTags != null && !dialogTags.isEmpty();
|
||||
}
|
||||
|
||||
public void storeTags(final String key, final int[] ids) {
|
||||
if (dialogTags == null) {
|
||||
dialogTags = new Object2ObjectArrayMap<>();
|
||||
}
|
||||
dialogTags.put(Key.stripMinecraftNamespace(key), ids);
|
||||
}
|
||||
|
||||
public int[] fromKey(final String key) {
|
||||
return dialogTags.get(Key.stripMinecraftNamespace(key));
|
||||
}
|
||||
|
||||
public CompoundTag[] fromRegistryKey(final String key) {
|
||||
final int[] ids = fromKey(key);
|
||||
if (ids == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final CompoundTag[] tags = new CompoundTag[ids.length];
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
tags[i] = fromRegistry(ids[i]);
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viaversion.api.connection.StorableObject;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectArrayMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectMap;
|
||||
|
||||
import static com.viaversion.viabackwards.utils.ChatUtil.translate;
|
||||
|
||||
public final class ServerLinks implements StorableObject {
|
||||
|
||||
private static final CompoundTag REPORT_BUG = translate("known_server_link.report_bug");
|
||||
private static final CompoundTag COMMUNITY_GUIDELINES = translate("known_server_link.community_guidelines");
|
||||
private static final CompoundTag SUPPORT = translate("known_server_link.support");
|
||||
private static final CompoundTag STATUS = translate("known_server_link.status");
|
||||
private static final CompoundTag FEEDBACK = translate("known_server_link.feedback");
|
||||
private static final CompoundTag COMMUNITY = translate("known_server_link.community");
|
||||
private static final CompoundTag WEBSITE = translate("known_server_link.website");
|
||||
private static final CompoundTag FORUMS = translate("known_server_link.forums");
|
||||
private static final CompoundTag NEWS = translate("known_server_link.news");
|
||||
private static final CompoundTag ANNOUNCEMENTS = translate("known_server_link.announcements");
|
||||
|
||||
private final Object2ObjectMap<Tag, String> links = new Object2ObjectArrayMap<>();
|
||||
|
||||
public void storeLink(final Tag tag, final String uri) {
|
||||
links.put(tag, uri);
|
||||
}
|
||||
|
||||
public void storeLink(final int id, final String uri) {
|
||||
switch (id) {
|
||||
case 1 -> storeLink(COMMUNITY_GUIDELINES, uri);
|
||||
case 2 -> storeLink(SUPPORT, uri);
|
||||
case 3 -> storeLink(STATUS, uri);
|
||||
case 4 -> storeLink(FEEDBACK, uri);
|
||||
case 5 -> storeLink(COMMUNITY, uri);
|
||||
case 6 -> storeLink(WEBSITE, uri);
|
||||
case 7 -> storeLink(FORUMS, uri);
|
||||
case 8 -> storeLink(NEWS, uri);
|
||||
case 9 -> storeLink(ANNOUNCEMENTS, uri);
|
||||
default -> storeLink(REPORT_BUG, uri);
|
||||
}
|
||||
}
|
||||
|
||||
public Object2ObjectMap<Tag, String> links() {
|
||||
return links;
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.task;
|
||||
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.Protocol1_21_6To1_21_5;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ChestDialogStorage;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.protocol.ProtocolRunnable;
|
||||
|
||||
public final class ChestDialogViewTask extends ProtocolRunnable {
|
||||
|
||||
public ChestDialogViewTask() {
|
||||
super(Protocol1_21_6To1_21_5.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(final UserConnection connection) {
|
||||
final ChestDialogStorage storage = connection.get(ChestDialogStorage.class);
|
||||
if (storage != null) {
|
||||
storage.tick(connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_7to1_21_6;
|
||||
|
||||
import com.viaversion.viabackwards.api.BackwardsProtocol;
|
||||
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
|
||||
import com.viaversion.viabackwards.api.rewriters.SoundRewriter;
|
||||
import com.viaversion.viabackwards.api.rewriters.text.NBTComponentRewriter;
|
||||
import com.viaversion.viabackwards.api.rewriters.text.TranslatableRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_7to1_21_6.rewriter.BlockItemPacketRewriter1_21_7;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_7to1_21_6.rewriter.EntityPacketRewriter1_21_7;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys1_21_5;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_6;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21_5;
|
||||
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
|
||||
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
|
||||
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
|
||||
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
|
||||
import com.viaversion.viaversion.data.item.ItemHasherBase;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundConfigurationPackets1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPacket1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPackets1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundConfigurationPackets1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPacket1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPackets1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_6to1_21_7.Protocol1_21_6To1_21_7;
|
||||
import com.viaversion.viaversion.rewriter.ParticleRewriter;
|
||||
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
|
||||
import com.viaversion.viaversion.rewriter.TagRewriter;
|
||||
import com.viaversion.viaversion.util.SerializerVersion;
|
||||
|
||||
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
|
||||
|
||||
public final class Protocol1_21_7To1_21_6 extends BackwardsProtocol<ClientboundPacket1_21_6, ClientboundPacket1_21_6, ServerboundPacket1_21_6, ServerboundPacket1_21_6> {
|
||||
|
||||
public static final BackwardsMappingData MAPPINGS = new BackwardsMappingData("1.21.7", "1.21.6", Protocol1_21_6To1_21_7.class);
|
||||
private final EntityPacketRewriter1_21_7 entityRewriter = new EntityPacketRewriter1_21_7(this);
|
||||
private final BlockItemPacketRewriter1_21_7 itemRewriter = new BlockItemPacketRewriter1_21_7(this);
|
||||
private final ParticleRewriter<ClientboundPacket1_21_6> particleRewriter = new ParticleRewriter<>(this);
|
||||
private final NBTComponentRewriter<ClientboundPacket1_21_6> translatableRewriter = new NBTComponentRewriter<>(this);
|
||||
private final TagRewriter<ClientboundPacket1_21_6> tagRewriter = new TagRewriter<>(this);
|
||||
|
||||
public Protocol1_21_7To1_21_6() {
|
||||
super(ClientboundPacket1_21_6.class, ClientboundPacket1_21_6.class, ServerboundPacket1_21_6.class, ServerboundPacket1_21_6.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerPackets() {
|
||||
super.registerPackets();
|
||||
|
||||
tagRewriter.registerGeneric(ClientboundPackets1_21_6.UPDATE_TAGS);
|
||||
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21_6.UPDATE_TAGS);
|
||||
|
||||
final SoundRewriter<ClientboundPacket1_21_6> soundRewriter = new SoundRewriter<>(this);
|
||||
soundRewriter.registerSound1_19_3(ClientboundPackets1_21_6.SOUND);
|
||||
soundRewriter.registerSound1_19_3(ClientboundPackets1_21_6.SOUND_ENTITY);
|
||||
soundRewriter.registerStopSound(ClientboundPackets1_21_6.STOP_SOUND);
|
||||
|
||||
new StatisticsRewriter<>(this).register(ClientboundPackets1_21_6.AWARD_STATS);
|
||||
|
||||
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_6.SET_ACTION_BAR_TEXT);
|
||||
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_6.SET_TITLE_TEXT);
|
||||
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_6.SET_SUBTITLE_TEXT);
|
||||
translatableRewriter.registerBossEvent(ClientboundPackets1_21_6.BOSS_EVENT);
|
||||
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_6.DISCONNECT);
|
||||
translatableRewriter.registerTabList(ClientboundPackets1_21_6.TAB_LIST);
|
||||
translatableRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21_6.PLAYER_COMBAT_KILL);
|
||||
translatableRewriter.registerPlayerInfoUpdate1_21_4(ClientboundPackets1_21_6.PLAYER_INFO_UPDATE);
|
||||
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_6.SYSTEM_CHAT);
|
||||
translatableRewriter.registerDisguisedChat(ClientboundPackets1_21_6.DISGUISED_CHAT);
|
||||
translatableRewriter.registerPlayerChat1_21_5(ClientboundPackets1_21_6.PLAYER_CHAT);
|
||||
translatableRewriter.registerPing();
|
||||
|
||||
particleRewriter.registerLevelParticles1_21_4(ClientboundPackets1_21_6.LEVEL_PARTICLES);
|
||||
particleRewriter.registerExplode1_21_2(ClientboundPackets1_21_6.EXPLODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(final UserConnection connection) {
|
||||
addEntityTracker(connection, new EntityTrackerBase(connection, EntityTypes1_21_6.PLAYER));
|
||||
addItemHasher(connection, new ItemHasherBase(this, connection, SerializerVersion.V1_21_6, SerializerVersion.V1_21_6));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BackwardsMappingData getMappingData() {
|
||||
return MAPPINGS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Types1_20_5<StructuredDataKeys1_21_5, EntityDataTypes1_21_5> types() {
|
||||
return VersionedTypes.V1_21_6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Types1_20_5<StructuredDataKeys1_21_5, EntityDataTypes1_21_5> mappedTypes() {
|
||||
return VersionedTypes.V1_21_6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TranslatableRewriter getComponentRewriter() {
|
||||
return translatableRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPacketRewriter1_21_7 getEntityRewriter() {
|
||||
return entityRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockItemPacketRewriter1_21_7 getItemRewriter() {
|
||||
return itemRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParticleRewriter<ClientboundPacket1_21_6> getParticleRewriter() {
|
||||
return particleRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TagRewriter<ClientboundPacket1_21_6> getTagRewriter() {
|
||||
return tagRewriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PacketTypesProvider<ClientboundPacket1_21_6, ClientboundPacket1_21_6, ServerboundPacket1_21_6, ServerboundPacket1_21_6> createPacketTypesProvider() {
|
||||
return new SimplePacketTypesProvider<>(
|
||||
packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_21_6.class, ClientboundConfigurationPackets1_21_6.class),
|
||||
packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_21_6.class, ClientboundConfigurationPackets1_21_6.class),
|
||||
packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_21_6.class, ServerboundConfigurationPackets1_21_6.class),
|
||||
packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_21_6.class, ServerboundConfigurationPackets1_21_6.class)
|
||||
);
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_7to1_21_6.rewriter;
|
||||
|
||||
import com.viaversion.viabackwards.api.rewriters.BackwardsStructuredItemRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_7to1_21_6.Protocol1_21_7To1_21_6;
|
||||
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_21_5;
|
||||
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.rewriter.RecipeDisplayRewriter1_21_5;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPacket1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPackets1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPacket1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPackets1_21_6;
|
||||
import com.viaversion.viaversion.rewriter.BlockRewriter;
|
||||
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
|
||||
|
||||
public final class BlockItemPacketRewriter1_21_7 extends BackwardsStructuredItemRewriter<ClientboundPacket1_21_6, ServerboundPacket1_21_6, Protocol1_21_7To1_21_6> {
|
||||
|
||||
public BlockItemPacketRewriter1_21_7(final Protocol1_21_7To1_21_6 protocol) {
|
||||
super(protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerPackets() {
|
||||
final BlockRewriter<ClientboundPacket1_21_6> blockRewriter = BlockRewriter.for1_20_2(protocol);
|
||||
blockRewriter.registerBlockEvent(ClientboundPackets1_21_6.BLOCK_EVENT);
|
||||
blockRewriter.registerBlockUpdate(ClientboundPackets1_21_6.BLOCK_UPDATE);
|
||||
blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21_6.SECTION_BLOCKS_UPDATE);
|
||||
blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21_6.LEVEL_EVENT, 2001);
|
||||
blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21_6.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_21_5::new);
|
||||
blockRewriter.registerBlockEntityData(ClientboundPackets1_21_6.BLOCK_ENTITY_DATA);
|
||||
|
||||
registerSetCursorItem(ClientboundPackets1_21_6.SET_CURSOR_ITEM);
|
||||
registerSetPlayerInventory(ClientboundPackets1_21_6.SET_PLAYER_INVENTORY);
|
||||
registerCooldown1_21_2(ClientboundPackets1_21_6.COOLDOWN);
|
||||
registerSetContent1_21_2(ClientboundPackets1_21_6.CONTAINER_SET_CONTENT);
|
||||
registerSetSlot1_21_2(ClientboundPackets1_21_6.CONTAINER_SET_SLOT);
|
||||
registerAdvancements1_20_3(ClientboundPackets1_21_6.UPDATE_ADVANCEMENTS);
|
||||
registerSetEquipment(ClientboundPackets1_21_6.SET_EQUIPMENT);
|
||||
registerMerchantOffers1_20_5(ClientboundPackets1_21_6.MERCHANT_OFFERS);
|
||||
registerContainerClick1_21_5(ServerboundPackets1_21_6.CONTAINER_CLICK);
|
||||
registerSetCreativeModeSlot1_21_5(ServerboundPackets1_21_6.SET_CREATIVE_MODE_SLOT);
|
||||
|
||||
final RecipeDisplayRewriter<ClientboundPacket1_21_6> recipeRewriter = new RecipeDisplayRewriter1_21_5<>(protocol);
|
||||
recipeRewriter.registerUpdateRecipes(ClientboundPackets1_21_6.UPDATE_RECIPES);
|
||||
recipeRewriter.registerRecipeBookAdd(ClientboundPackets1_21_6.RECIPE_BOOK_ADD);
|
||||
recipeRewriter.registerPlaceGhostRecipe(ClientboundPackets1_21_6.PLACE_GHOST_RECIPE);
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
|
||||
* Copyright (C) 2016-2025 ViaVersion and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.viaversion.viabackwards.protocol.v1_21_7to1_21_6.rewriter;
|
||||
|
||||
import com.viaversion.viabackwards.api.rewriters.BackwardsRegistryRewriter;
|
||||
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
|
||||
import com.viaversion.viabackwards.protocol.v1_21_7to1_21_6.Protocol1_21_7To1_21_6;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_4;
|
||||
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_6;
|
||||
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21_5;
|
||||
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundConfigurationPackets1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPacket1_21_6;
|
||||
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPackets1_21_6;
|
||||
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
|
||||
|
||||
public final class EntityPacketRewriter1_21_7 extends EntityRewriter<ClientboundPacket1_21_6, Protocol1_21_7To1_21_6> {
|
||||
|
||||
public EntityPacketRewriter1_21_7(final Protocol1_21_7To1_21_6 protocol) {
|
||||
super(protocol, VersionedTypes.V1_21_6.entityDataTypes.optionalComponentType, VersionedTypes.V1_21_6.entityDataTypes.booleanType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerPackets() {
|
||||
registerTrackerWithData1_19(ClientboundPackets1_21_6.ADD_ENTITY, EntityTypes1_21_4.FALLING_BLOCK);
|
||||
registerSetEntityData(ClientboundPackets1_21_6.SET_ENTITY_DATA);
|
||||
registerRemoveEntities(ClientboundPackets1_21_6.REMOVE_ENTITIES);
|
||||
registerPlayerAbilities(ClientboundPackets1_21_6.PLAYER_ABILITIES);
|
||||
registerGameEvent(ClientboundPackets1_21_6.GAME_EVENT);
|
||||
registerLogin1_20_5(ClientboundPackets1_21_6.LOGIN);
|
||||
registerRespawn1_20_5(ClientboundPackets1_21_6.RESPAWN);
|
||||
|
||||
final RegistryDataRewriter registryDataRewriter = new BackwardsRegistryRewriter(protocol);
|
||||
protocol.registerClientbound(ClientboundConfigurationPackets1_21_6.REGISTRY_DATA, registryDataRewriter::handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerRewrites() {
|
||||
final EntityDataTypes1_21_5 mappedEntityDataTypes = VersionedTypes.V1_21_6.entityDataTypes;
|
||||
registerEntityDataTypeHandler1_20_3(
|
||||
mappedEntityDataTypes.itemType,
|
||||
mappedEntityDataTypes.blockStateType,
|
||||
mappedEntityDataTypes.optionalBlockStateType,
|
||||
mappedEntityDataTypes.particleType,
|
||||
mappedEntityDataTypes.particlesType,
|
||||
mappedEntityDataTypes.componentType,
|
||||
mappedEntityDataTypes.optionalComponentType
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType typeFromId(final int type) {
|
||||
return EntityTypes1_21_6.getTypeFromId(type);
|
||||
}
|
||||
}
|
||||
+62
-30
@@ -19,6 +19,7 @@ package com.viaversion.viabackwards.protocol.v1_21to1_20_5.rewriter;
|
||||
|
||||
import com.viaversion.nbt.tag.ByteTag;
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.nbt.tag.ListTag;
|
||||
import com.viaversion.nbt.tag.StringTag;
|
||||
import com.viaversion.nbt.tag.Tag;
|
||||
import com.viaversion.viabackwards.api.rewriters.BackwardsStructuredItemRewriter;
|
||||
@@ -35,6 +36,9 @@ import com.viaversion.viaversion.api.minecraft.SoundEvent;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
|
||||
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers1_21;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers1_21.AttributeModifier;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.AttributeModifiers1_21.ModifierData;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
|
||||
import com.viaversion.viaversion.api.minecraft.item.data.JukeboxPlayable;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
@@ -271,51 +275,79 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe
|
||||
final StructuredDataContainer data = item.dataContainer();
|
||||
data.setIdLookup(protocol, true);
|
||||
|
||||
final CompoundTag backupTag = new CompoundTag();
|
||||
|
||||
final JukeboxPlayable jukeboxPlayable = data.get(StructuredDataKey.JUKEBOX_PLAYABLE1_21);
|
||||
if (jukeboxPlayable == null) {
|
||||
return;
|
||||
if (jukeboxPlayable != null) {
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
if (jukeboxPlayable.song().hasHolder()) {
|
||||
final Holder<JukeboxPlayable.JukeboxSong> songHolder = jukeboxPlayable.song().holder();
|
||||
tag.put("song", holderToTag(songHolder, (song, songTag) -> {
|
||||
saveSoundEventHolder(songTag, song.soundEvent());
|
||||
songTag.put("description", song.description());
|
||||
songTag.putFloat("length_in_seconds", song.lengthInSeconds());
|
||||
songTag.putInt("comparator_output", song.comparatorOutput());
|
||||
}));
|
||||
} else {
|
||||
tag.putString("song_identifier", jukeboxPlayable.song().key());
|
||||
}
|
||||
tag.putBoolean("show_in_tooltip", jukeboxPlayable.showInTooltip());
|
||||
|
||||
backupTag.put("jukebox_playable", tag);
|
||||
}
|
||||
|
||||
final CompoundTag tag = new CompoundTag();
|
||||
if (jukeboxPlayable.song().hasHolder()) {
|
||||
final Holder<JukeboxPlayable.JukeboxSong> songHolder = jukeboxPlayable.song().holder();
|
||||
tag.put("song", holderToTag(songHolder, (song, songTag) -> {
|
||||
saveSoundEventHolder(songTag, song.soundEvent());
|
||||
songTag.put("description", song.description());
|
||||
songTag.putFloat("length_in_seconds", song.lengthInSeconds());
|
||||
songTag.putInt("comparator_output", song.comparatorOutput());
|
||||
}));
|
||||
} else {
|
||||
tag.putString("song_identifier", jukeboxPlayable.song().key());
|
||||
final AttributeModifiers1_21 attributeModifiers = data.get(StructuredDataKey.ATTRIBUTE_MODIFIERS1_21);
|
||||
if (attributeModifiers != null) {
|
||||
final ListTag<StringTag> attributeIds = new ListTag<>(StringTag.class);
|
||||
for (final AttributeModifier modifier : attributeModifiers.modifiers()) {
|
||||
attributeIds.add(new StringTag(modifier.modifier().id()));
|
||||
}
|
||||
backupTag.put("attribute_modifiers", attributeIds);
|
||||
}
|
||||
tag.putBoolean("show_in_tooltip", jukeboxPlayable.showInTooltip());
|
||||
|
||||
saveTag(createCustomTag(item), tag, "jukebox_playable");
|
||||
if (!backupTag.isEmpty()) {
|
||||
saveTag(createCustomTag(item), backupTag, "inconvertible_data");
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreInconvertibleData(final Item item) {
|
||||
final StructuredDataContainer data = item.dataContainer();
|
||||
final CompoundTag customData = data.get(StructuredDataKey.CUSTOM_DATA);
|
||||
if (customData == null || !(customData.remove(nbtTagName("jukebox_playable")) instanceof CompoundTag tag)) {
|
||||
if (customData == null || !(customData.remove(nbtTagName("inconvertible_data")) instanceof CompoundTag tag)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final EitherHolder<JukeboxPlayable.JukeboxSong> song;
|
||||
final String songIdentifier = tag.getString("song_identifier");
|
||||
if (songIdentifier != null) {
|
||||
song = EitherHolder.of(songIdentifier);
|
||||
} else {
|
||||
song = EitherHolder.of(restoreHolder(tag, "song", songTag -> {
|
||||
final Holder<SoundEvent> soundEvent = restoreSoundEventHolder(songTag);
|
||||
final Tag description = songTag.get("description");
|
||||
final float lengthInSeconds = songTag.getFloat("length_in_seconds");
|
||||
final int comparatorOutput = songTag.getInt("comparator_output");
|
||||
return new JukeboxPlayable.JukeboxSong(soundEvent, description, lengthInSeconds, comparatorOutput);
|
||||
}));
|
||||
final CompoundTag jukeboxPlayableTag = tag.getCompoundTag("jukebox_playable");
|
||||
if (jukeboxPlayableTag != null) {
|
||||
final EitherHolder<JukeboxPlayable.JukeboxSong> song;
|
||||
final String songIdentifier = tag.getString("song_identifier");
|
||||
if (songIdentifier != null) {
|
||||
song = EitherHolder.of(songIdentifier);
|
||||
} else {
|
||||
song = EitherHolder.of(restoreHolder(tag, "song", songTag -> {
|
||||
final Holder<SoundEvent> soundEvent = restoreSoundEventHolder(songTag);
|
||||
final Tag description = songTag.get("description");
|
||||
final float lengthInSeconds = songTag.getFloat("length_in_seconds");
|
||||
final int comparatorOutput = songTag.getInt("comparator_output");
|
||||
return new JukeboxPlayable.JukeboxSong(soundEvent, description, lengthInSeconds, comparatorOutput);
|
||||
}));
|
||||
}
|
||||
|
||||
final JukeboxPlayable jukeboxPlayable = new JukeboxPlayable(song, tag.getBoolean("show_in_tooltip"));
|
||||
data.set(StructuredDataKey.JUKEBOX_PLAYABLE1_21, jukeboxPlayable);
|
||||
}
|
||||
|
||||
final ListTag<StringTag> attributeIds = tag.getListTag("attribute_modifiers", StringTag.class);
|
||||
final AttributeModifiers1_21 attributeModifiers = data.get(StructuredDataKey.ATTRIBUTE_MODIFIERS1_21);
|
||||
if (attributeIds != null && attributeModifiers != null && attributeIds.size() == attributeModifiers.modifiers().length) {
|
||||
for (int i = 0; i < attributeIds.size(); i++) {
|
||||
final String id = attributeIds.get(i).getValue();
|
||||
final AttributeModifier modifier = attributeModifiers.modifiers()[i];
|
||||
final ModifierData updatedModifierData = new ModifierData(id, modifier.modifier().amount(), modifier.modifier().operation());
|
||||
attributeModifiers.modifiers()[i] = new AttributeModifier(modifier.attribute(), updatedModifierData, modifier.slotType());
|
||||
}
|
||||
}
|
||||
|
||||
final JukeboxPlayable jukeboxPlayable = new JukeboxPlayable(song, tag.getBoolean("show_in_tooltip"));
|
||||
data.set(StructuredDataKey.JUKEBOX_PLAYABLE1_21, jukeboxPlayable);
|
||||
removeCustomTag(data, customData);
|
||||
}
|
||||
|
||||
|
||||
-2
@@ -34,8 +34,6 @@ import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1
|
||||
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
|
||||
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
||||
import com.viaversion.viaversion.api.type.Types;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
|
||||
import com.viaversion.viaversion.api.type.types.version.Types1_21;
|
||||
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
|
||||
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5;
|
||||
import com.viaversion.viaversion.protocols.v1_20_5to1_21.data.Paintings1_20_5;
|
||||
|
||||
Loaded 100 of 112 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user