Compare commits

...
43 Commits
Author SHA1 Message Date
Nassim Jahnke 1f5fd88fef 5.6.0 Release 2025-12-12 16:00:57 +01:00
Nassim Jahnke 531f7d078e Remove nautilus variant in 1.21.11 component rewriter 2025-12-12 16:00:57 +01:00
Nassim Jahnke 2806671813 Add translatables 2025-12-12 16:00:56 +01:00
Nassim Jahnke 7634a7ec7a Add fog effects to dimensions and biomes 2025-12-12 16:00:56 +01:00
Nassim Jahnke 8cd5bd3368 1.21.11-pre4 2025-12-12 16:00:56 +01:00
Nassim Jahnke 0735e4afb5 Handle biome color type changes 2025-12-12 16:00:56 +01:00
Nassim Jahnke 3568eee8f2 Back up new item data 2025-12-12 16:00:55 +01:00
Nassim Jahnke e694b3532a 1.21.11-pre1 2025-12-12 16:00:55 +01:00
Nassim Jahnke 2bcf79c501 25w46a 2025-12-12 16:00:55 +01:00
Nassim Jahnke 7ded34c55e 25w45a 2025-12-12 16:00:55 +01:00
Nassim Jahnke 3bdeed8a9f 25w43a 2025-12-12 16:00:54 +01:00
Nassim Jahnke 30df707369 WIP 25w42a 2025-12-12 16:00:54 +01:00
github-actions[bot]andgradle-update-robot cf8058016c Update Gradle Wrapper from 9.2.0 to 9.2.1 (#1141)
Signed-off-by: gradle-update-robot <gradle-update-robot@regolo.cc>
Co-authored-by: gradle-update-robot <gradle-update-robot@regolo.cc>
2025-12-12 15:58:35 +01:00
Kichura 3468b0a785 Update workflow configs (#1144) 2025-12-06 20:34:00 +01:00
tmpod d273b06e05 Fix text components in signs not being rewritten in 1.21.9→1.21.7 (#1147) 2025-12-06 20:14:36 +01:00
dependabot[bot] 4f561ba4a7 Bump actions/checkout from 5 to 6 (#1142)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 21:58:08 +01:00
Nanashi.andFlorianMichael 0a5035d209 More dialog emulation fixes (#1131)
Co-authored-by: FlorianMichael <florian.michael07@gmail.com>
2025-11-24 21:57:46 +01:00
Nassim Jahnke 609b657c68 Handle set_player_team text component changes 2025-11-23 19:47:05 +01:00
Nassim Jahnke 5885074fcd [ci skip] Update issue template 2025-11-18 19:50:03 +01:00
Nassim Jahnke d499918e4b Don't cancel full equipment containing saddle in 1.21.5->1.21.4
Plugins manually sending equipment packets may include saddles for entities that shouldn't have saddle equipment, though the client will ignore them
Closes #1140
2025-11-18 19:33:34 +01:00
FlorianMichael 17d7b4873f Set accepted = true in 1.12->1.11.1 shift click fix (#1139) 2025-11-16 19:04:17 +01:00
FlorianMichael 38243bad78 [ci skip] Update ViaFabricPlus jars path (#1133) 2025-11-12 16:58:40 +01:00
Nassim Jahnke 50577abbb5 Fix jukebox_playable backup
Fixes #1130
2025-11-08 10:45:51 +01:00
github-actions[bot]andgradle-update-robot 277de42948 Update Gradle Wrapper from 9.1.0 to 9.2.0 (#1129)
Signed-off-by: gradle-update-robot <gradle-update-robot@regolo.cc>
Co-authored-by: gradle-update-robot <gradle-update-robot@regolo.cc>
2025-11-03 16:52:13 +01:00
FlorianMichael 4c26915fdf Fix text display y offset in 1.19.4->1.19.3 (#1128) 2025-11-01 15:07:36 +01:00
FlorianMichael 7c98b75543 Cancel sign editor open packet for invalid positions in 1.21.2->1.21 (#1099) 2025-11-01 14:59:13 +01:00
Nassim Jahnke 7d39bcc365 Fix regression in cancelling new 1.21.5 registries 2025-10-28 21:11:26 +01:00
Nassim Jahnke 85688beba8 Go through normal registry handling for removed registries in 1.21.5->1.21.4 2025-10-20 14:28:26 +02:00
FlorianMichael fd16c4469c Add option to disable dialog handling in 1.21.6->1.21.5 (#1116) 2025-10-18 18:34:23 +02:00
Nassim Jahnke a37605e920 Update VV usage 2025-10-14 17:59:53 +02:00
FlorianMichael 1d4e41f867 Fix custom action button in notice dialogs not added in 1.21.6->1.21.5 (#1117) 2025-10-13 20:30:47 +02:00
Nassim Jahnke 1f4acbbc60 5.5.1 Release 2025-10-12 18:43:52 +02:00
Nassim Jahnke eff547019c Remove instrument and jukebox playable in show_item hovers in 1.21.5->1.21.4 2025-10-12 18:43:17 +02:00
Nassim Jahnke bbb52f575a Add --refresh-dependencies to publish workflow 2025-10-07 16:14:10 +02:00
Nassim Jahnke 74ad2d15fb Update VV usage again 2025-10-07 15:39:19 +02:00
Nassim Jahnke 024fe774f4 Update VV usage 2025-10-07 15:26:05 +02:00
dependabot[bot] 0df9c50251 Bump gradle/actions from 4 to 5 (#1115)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-06 23:37:26 +02:00
Nassim Jahnke e8637e5753 Update sound mapping format
VV now includes full sound name mappings, so VB can map them via registry indexes and doesn't need the extra sound file anymore
2025-10-06 20:44:10 +02:00
Nassim Jahnke 64b454de6f Fix world border scale in 1.21.9->1.21.7 2025-10-05 22:20:44 +02:00
FlorianMichael 433f46e34e Handle DEBUG_SAMPLE_SUBSCRIPTION structure change in 1.21.9 ->1.21.7 (#1111) 2025-10-05 08:49:11 +02:00
Nassim Jahnke fbe6a67750 Fix inverted hidden components checks in 1.21.5->1.21.4
Fixes #1110
2025-10-04 11:02:49 +02:00
Nassim Jahnke 454e97c844 Don't remove font
Closes #1109
2025-10-04 10:08:01 +02:00
FlorianMichael fccea9b55d Throw out object components in 1.21.9->1.21.7 (#1108) 2025-10-03 21:42:31 +02:00
96 changed files with 1647 additions and 1645 deletions

No files matched your search

+2 -11
View File
@@ -48,21 +48,12 @@ body:
label: Steps to Reproduce
description: |
List the steps on how we can reproduce the issue. Make sure we can easily understand what you mean with each step.
**Please always include the client version(s) with which the issue happens. Ideally also try to find out from what specific version downward/in what version range the issue happens.**
placeholder: |
Example:
1. Login with a 1.16.5 client
2. Place a sign
3. The sign text is displayed wrong
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: |
Describe what exactly you expected to happen.
placeholder: |
Example: "Placed sign text should not disappear."
3. The sign text disappears
validations:
required: true
+3 -1
View File
@@ -1,6 +1,8 @@
version: 2
updates:
- package-ecosystem: "github-actions"
cooldown:
default-days: 7
directory: "/"
schedule:
interval: "weekly"
interval: "monthly"
+8 -8
View File
@@ -1,22 +1,22 @@
name: Java CI with Gradle
on: [push, pull_request]
name: Build
on: [pull_request, push, workflow_dispatch]
permissions:
contents: read
jobs:
build:
# Only run on PRs if the source branch is on a different repo. We do not need to run everything twice.
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@v5
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # 6.0.0
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # 5.0.0
- name: Set up JDK 17
uses: actions/setup-java@v5
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # 5.0.0
with:
distribution: 'temurin'
java-version: 17
+8 -5
View File
@@ -6,25 +6,28 @@ on:
- dev
workflow_dispatch:
permissions:
contents: read
jobs:
publish:
if: github.repository_owner == 'ViaVersion'
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@v5
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # 6.0.0
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
uses: gradle/actions/setup-gradle@4d9f0ba0025fe599b4ebab900eb7f3a1d93ef4c2 # 5.0.0
- name: Set up JDK 17
uses: actions/setup-java@v5
uses: actions/setup-java@dded0888837ed1f317902acf8a20df0ad188d165 # 5.0.0
with:
distribution: 'temurin'
java-version: 17
check-latest: true
- name: Build
run: ./gradlew build
- name: Build with Gradle
run: ./gradlew build --refresh-dependencies
- name: Publish to Hangar
env:
HANGAR_TOKEN: ${{ secrets.HANGAR_TOKEN }}
+7 -2
View File
@@ -4,13 +4,18 @@ on:
schedule:
- cron: "0 0 * * 0"
permissions:
contents: write
pull-requests: write
jobs:
update-gradle-wrapper:
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@v5
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # 6.0.0
with:
fetch-depth: 0
persist-credentials: false
- name: Update Gradle Wrapper
uses: gradle-update/update-gradle-wrapper-action@v2
uses: gradle-update/update-gradle-wrapper-action@512b1875f3b6270828abfe77b247d5895a2da1e5 # 2.1.0
+1 -1
View File
@@ -12,7 +12,7 @@ Supported Versions
-
As a plugin, ViaBackwards runs on servers on releases 1.10-latest. You can also use ViaBackwards in ViaFabric or ViaFabricPlus.
- in **ViaFabric**, put ViaBackwards into the `mods` folder
- in **ViaFabricPlus**, put ViaBackwards into the `ViaFabricPlus/jars` folder
- in **ViaFabricPlus**, put ViaBackwards into the `config/viafabriclus/jars` folder
See [HERE](https://viaversion.com) for an overview of the different Via* projects.
@@ -44,6 +44,7 @@ public class ViaBackwardsConfig extends Config implements com.viaversion.viaback
private boolean mapCustomModelData;
private boolean mapDisplayEntities;
private boolean suppressEmulationWarnings;
private boolean dialogsViaChests;
private DialogStyleConfig dialogStyleConfig;
public ViaBackwardsConfig(File configFile, Logger logger) {
@@ -70,6 +71,7 @@ public class ViaBackwardsConfig extends Config implements com.viaversion.viaback
mapCustomModelData = getBoolean("map-custom-model-data", true);
mapDisplayEntities = getBoolean("map-display-entities", true);
suppressEmulationWarnings = getBoolean("suppress-emulation-warnings", false);
dialogsViaChests = getBoolean("dialogs-via-chests", true);
dialogStyleConfig = loadDialogStyleConfig(getSection("dialog-style"));
}
@@ -160,6 +162,11 @@ public class ViaBackwardsConfig extends Config implements com.viaversion.viaback
return suppressEmulationWarnings;
}
@Override
public boolean dialogsViaChests() {
return dialogsViaChests;
}
@Override
public DialogStyleConfig dialogStyleConfig() {
return dialogStyleConfig;
@@ -113,6 +113,13 @@ public interface ViaBackwardsConfig extends Config {
*/
boolean suppressEmulationWarnings();
/**
* If enabled, dialogs will be shown via chest inventories for 1.21.5 clients on 1.21.6+ servers.
*
* @return true if enabled
*/
boolean dialogsViaChests();
/**
* Returns the dialog style configuration.
*
@@ -55,6 +55,7 @@ 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_20to1_19_4.Protocol1_20To1_19_4;
import com.viaversion.viabackwards.protocol.v1_21_11to1_21_9.Protocol1_21_11To1_21_9;
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;
@@ -77,7 +78,7 @@ import java.util.logging.Logger;
public interface ViaBackwardsPlatform {
String MINIMUM_VV_VERSION = "5.5.0";
String MINIMUM_VV_VERSION = "5.6.0";
/**
* Initialize ViaBackwards.
@@ -156,6 +157,7 @@ public interface ViaBackwardsPlatform {
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);
protocolManager.registerProtocol(new Protocol1_21_9To1_21_7(), ProtocolVersion.v1_21_7, ProtocolVersion.v1_21_9);
protocolManager.registerProtocol(new Protocol1_21_11To1_21_9(), ProtocolVersion.v1_21_9, ProtocolVersion.v1_21_11);
}
default void enable() {
@@ -34,7 +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.viaversion.util.Key;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
@@ -45,7 +44,6 @@ public class BackwardsMappingData extends MappingDataBase {
private final Class<? extends Protocol<?, ?, ?, ?>> vvProtocolClass;
protected Int2ObjectMap<MappedItem> backwardsItemMappings;
private Map<String, String> backwardsSoundMappings;
private Map<String, String> entityNames;
private Int2ObjectMap<String> enchantmentNames;
@@ -83,7 +81,6 @@ public class BackwardsMappingData extends MappingDataBase {
this.entityNames = loadNameByStringMappings(data, "entitynames");
this.enchantmentNames = loadNameByIdMappings(data, "enchantmentnames");
this.backwardsSoundMappings = loadNameByStringMappings(data, "soundnames");
}
private @Nullable Map<String, String> loadNameByStringMappings(final CompoundTag data, final String key) {
@@ -161,10 +158,7 @@ public class BackwardsMappingData extends MappingDataBase {
}
public @Nullable String getMappedNamedSound(final String id) {
if (backwardsSoundMappings == null) {
return null;
}
return backwardsSoundMappings.get(Key.stripMinecraftNamespace(id));
return getFullSoundMappings().mappedIdentifier(id);
}
public @Nullable String mappedEntityName(final String entityName) {
@@ -187,10 +181,6 @@ public class BackwardsMappingData extends MappingDataBase {
return backwardsItemMappings;
}
public @Nullable Map<String, String> getBackwardsSoundMappings() {
return backwardsSoundMappings;
}
public @Nullable Class<? extends Protocol<?, ?, ?, ?>> getViaVersionProtocolClass() {
return vvProtocolClass;
}
@@ -300,7 +300,11 @@ public class BackwardsStructuredItemRewriter<C extends ClientboundPacketType, S
}
protected Holder<SoundEvent> restoreSoundEventHolder(final CompoundTag tag) {
return restoreHolder(tag, "sound_event", soundEventTag -> {
return restoreSoundEventHolder(tag, "sound_event");
}
protected Holder<SoundEvent> restoreSoundEventHolder(final CompoundTag tag, final String key) {
return restoreHolder(tag, key, soundEventTag -> {
final String identifier = soundEventTag.getString("identifier");
final FloatTag fixedRange = soundEventTag.getFloatTag("fixed_range");
return new SoundEvent(identifier, fixedRange != null ? fixedRange.asFloat() : null);
@@ -17,16 +17,13 @@
*/
package com.viaversion.viabackwards.protocol.template;
import com.viaversion.viabackwards.api.rewriters.BackwardsRegistryRewriter;
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_4;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21_2;
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
// Replace if needed
// VersionedTypes
@@ -45,9 +42,6 @@ final class EntityPacketRewriter1_99 extends EntityRewriter<ClientboundPacket1_2
registerGameEvent(ClientboundPackets1_21_2.GAME_EVENT);
registerLogin1_20_5(ClientboundPackets1_21_2.LOGIN);
registerRespawn1_20_5(ClientboundPackets1_21_2.RESPAWN);
final RegistryDataRewriter registryDataRewriter = new BackwardsRegistryRewriter(protocol);
protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, registryDataRewriter::handle);
}
@Override
@@ -19,6 +19,7 @@ package com.viaversion.viabackwards.protocol.template;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
import com.viaversion.viabackwards.api.rewriters.BackwardsRegistryRewriter;
import com.viaversion.viabackwards.api.rewriters.SoundRewriter;
import com.viaversion.viabackwards.api.rewriters.text.NBTComponentRewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
@@ -37,9 +38,9 @@ import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.packet.ServerboundPac
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
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;
@@ -62,6 +63,7 @@ final class Protocol1_99To1_98 extends BackwardsProtocol<ClientboundPacket1_21_2
private final ParticleRewriter<ClientboundPacket1_21_2> particleRewriter = new ParticleRewriter<>(this);
private final NBTComponentRewriter<ClientboundPacket1_21_2> translatableRewriter = new ComponentRewriter1_99(this);
private final TagRewriter<ClientboundPacket1_21_2> tagRewriter = new TagRewriter<>(this);
private final RegistryDataRewriter registryDataRewriter = new BackwardsRegistryRewriter(this);
public Protocol1_99To1_98() {
super(ClientboundPacket1_21_2.class, ClientboundPacket1_21_2.class, ServerboundPacket1_21_4.class, ServerboundPacket1_21_4.class);
@@ -71,6 +73,8 @@ final class Protocol1_99To1_98 extends BackwardsProtocol<ClientboundPacket1_21_2
protected void registerPackets() {
super.registerPackets();
registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, registryDataRewriter::handle);
tagRewriter.registerGeneric(ClientboundPackets1_21_2.UPDATE_TAGS);
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21.UPDATE_TAGS);
@@ -90,6 +94,7 @@ final class Protocol1_99To1_98 extends BackwardsProtocol<ClientboundPacket1_21_2
translatableRewriter.registerBossEvent(ClientboundPackets1_21_2.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_21_2.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_21_5(ClientboundPackets1_21_2.SET_PLAYER_TEAM);
translatableRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21_2.PLAYER_COMBAT_KILL);
translatableRewriter.registerPlayerInfoUpdate1_21_4(ClientboundPackets1_21_2.PLAYER_INFO_UPDATE);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.SYSTEM_CHAT);
@@ -123,6 +128,11 @@ final class Protocol1_99To1_98 extends BackwardsProtocol<ClientboundPacket1_21_2
return itemRewriter;
}
@Override
public RegistryDataRewriter getRegistryDataRewriter() {
return registryDataRewriter;
}
@Override
public ParticleRewriter<ClientboundPacket1_21_2> getParticleRewriter() {
return particleRewriter;
@@ -114,7 +114,7 @@ public class BlockItemPacketRewriter1_12 extends LegacyBlockItemRewriter<Clientb
PacketWrapper confirm = wrapper.create(ServerboundPackets1_12.CONTAINER_ACK);
confirm.write(Types.BYTE, wrapper.get(Types.BYTE, 0));
confirm.write(Types.SHORT, wrapper.get(Types.SHORT, 1));
confirm.write(Types.BOOLEAN, false); // Success - not used
confirm.write(Types.BOOLEAN, true); // Success - not used
wrapper.sendToServer(Protocol1_12To1_11_1.class);
wrapper.cancel();
@@ -69,6 +69,7 @@ public class Protocol1_13_1To1_13 extends BackwardsProtocol<ClientboundPackets1_
translatableRewriter.registerPlayerCombat(ClientboundPackets1_13.PLAYER_COMBAT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_13.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_13.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_13.SET_PLAYER_TEAM);
translatableRewriter.registerTitle(ClientboundPackets1_13.SET_TITLES);
translatableRewriter.registerPing();
@@ -62,6 +62,7 @@ public class Protocol1_14To1_13_2 extends BackwardsProtocol<ClientboundPackets1_
translatableRewriter.registerPlayerCombat(ClientboundPackets1_14.PLAYER_COMBAT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_14.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_14.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_14.SET_PLAYER_TEAM);
translatableRewriter.registerTitle(ClientboundPackets1_14.SET_TITLES);
translatableRewriter.registerPing();
@@ -64,6 +64,7 @@ public class Protocol1_15To1_14_4 extends BackwardsProtocol<ClientboundPackets1_
translatableRewriter.registerComponentPacket(ClientboundPackets1_15.DISCONNECT);
translatableRewriter.registerOpenScreen1_14(ClientboundPackets1_15.OPEN_SCREEN);
translatableRewriter.registerTabList(ClientboundPackets1_15.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_15.SET_PLAYER_TEAM);
translatableRewriter.registerTitle(ClientboundPackets1_15.SET_TITLES);
translatableRewriter.registerPing();
@@ -67,6 +67,7 @@ public class Protocol1_16_2To1_16_1 extends BackwardsProtocol<ClientboundPackets
translatableRewriter.registerComponentPacket(ClientboundPackets1_16_2.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_16_2.TAB_LIST);
translatableRewriter.registerTitle(ClientboundPackets1_16_2.SET_TITLES);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_16_2.SET_PLAYER_TEAM);
translatableRewriter.registerOpenScreen1_14(ClientboundPackets1_16_2.OPEN_SCREEN);
translatableRewriter.registerPing();
@@ -70,6 +70,7 @@ public class Protocol1_16To1_15_2 extends BackwardsProtocol<ClientboundPackets1_
translatableRewriter.registerPlayerCombat(ClientboundPackets1_16.PLAYER_COMBAT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_16.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_16.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_16.SET_PLAYER_TEAM);
translatableRewriter.registerTitle(ClientboundPackets1_16.SET_TITLES);
translatableRewriter.registerPing();
@@ -74,6 +74,7 @@ public final class Protocol1_17To1_16_4 extends BackwardsProtocol<ClientboundPac
translatableRewriter.registerBossEvent(ClientboundPackets1_17.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_17.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_17.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_17.SET_PLAYER_TEAM);
translatableRewriter.registerOpenScreen1_14(ClientboundPackets1_17.OPEN_SCREEN);
translatableRewriter.registerPing();
@@ -102,7 +103,7 @@ public final class Protocol1_17To1_16_4 extends BackwardsProtocol<ClientboundPac
// Put them into the hardcoded order of Vanilla tags (and only those), rewrite ids
for (RegistryType type : TAG_REGISTRY_TYPES) {
List<TagData> tagList = tags.get(type.resourceLocation());
List<TagData> tagList = tags.get(type.identifier());
if (tagList == null) {
// Higher versions may not send the otherwise expected tags
wrapper.write(Types.VAR_INT, 0);
@@ -82,6 +82,7 @@ public final class Protocol1_19_1To1_19 extends BackwardsProtocol<ClientboundPac
translatableRewriter.registerBossEvent(ClientboundPackets1_19_1.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_19_1.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_19_1.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_19_1.SET_PLAYER_TEAM);
translatableRewriter.registerOpenScreen1_14(ClientboundPackets1_19_1.OPEN_SCREEN);
translatableRewriter.registerPlayerCombatKill(ClientboundPackets1_19_1.PLAYER_COMBAT_KILL);
translatableRewriter.registerPing();
@@ -19,10 +19,10 @@ package com.viaversion.viabackwards.protocol.v1_19_3to1_19_1;
import com.google.common.base.Preconditions;
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.JsonNBTComponentRewriter;
import com.viaversion.viabackwards.protocol.v1_19_1to1_19.Protocol1_19_1To1_19;
import com.viaversion.viabackwards.protocol.v1_19_3to1_19_1.data.BackwardsMappingData1_19_3;
import com.viaversion.viabackwards.protocol.v1_19_3to1_19_1.rewriter.BlockItemPacketRewriter1_19_3;
import com.viaversion.viabackwards.protocol.v1_19_3to1_19_1.rewriter.EntityPacketRewriter1_19_3;
import com.viaversion.viabackwards.protocol.v1_19_3to1_19_1.storage.ChatSessionStorage;
@@ -49,6 +49,7 @@ import com.viaversion.viaversion.data.entity.EntityTrackerBase;
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_19_1to1_19_3.Protocol1_19_1To1_19_3;
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;
@@ -68,7 +69,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public final class Protocol1_19_3To1_19_1 extends BackwardsProtocol<ClientboundPackets1_19_3, ClientboundPackets1_19_1, ServerboundPackets1_19_3, ServerboundPackets1_19_1> {
public static final BackwardsMappingData1_19_3 MAPPINGS = new BackwardsMappingData1_19_3();
public static final BackwardsMappingData MAPPINGS = new BackwardsMappingData("1.19.3", "1.19", Protocol1_19_1To1_19_3.class);
public static final ByteArrayType.OptionalByteArrayType OPTIONAL_SIGNATURE_BYTES_TYPE = new ByteArrayType.OptionalByteArrayType(256);
public static final ByteArrayType SIGNATURE_BYTES_TYPE = new ByteArrayType(256);
private final EntityPacketRewriter1_19_3 entityRewriter = new EntityPacketRewriter1_19_3(this);
@@ -92,6 +93,7 @@ public final class Protocol1_19_3To1_19_1 extends BackwardsProtocol<ClientboundP
translatableRewriter.registerBossEvent(ClientboundPackets1_19_3.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_19_3.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_19_3.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_19_3.SET_PLAYER_TEAM);
translatableRewriter.registerOpenScreen1_14(ClientboundPackets1_19_3.OPEN_SCREEN);
translatableRewriter.registerPlayerCombatKill(ClientboundPackets1_19_3.PLAYER_COMBAT_KILL);
translatableRewriter.registerPing();
@@ -113,7 +115,7 @@ public final class Protocol1_19_3To1_19_1 extends BackwardsProtocol<ClientboundP
return;
}
final int mappedId = MAPPINGS.mappedSound(mappedIdentifier);
final int mappedId = MAPPINGS.getFullSoundMappings().mappedId(mappedIdentifier);
if (mappedId == -1) {
wrapper.cancel();
return;
@@ -401,7 +403,7 @@ public final class Protocol1_19_3To1_19_1 extends BackwardsProtocol<ClientboundP
}
@Override
public BackwardsMappingData1_19_3 getMappingData() {
public BackwardsMappingData getMappingData() {
return MAPPINGS;
}
@@ -1,53 +0,0 @@
/*
* 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_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.viaversion.protocols.v1_19_1to1_19_3.Protocol1_19_1To1_19_3;
import com.viaversion.viaversion.util.Key;
public final class BackwardsMappingData1_19_3 extends BackwardsMappingData {
private final Object2IntMap<String> mappedSounds = new Object2IntOpenHashMap<>();
public BackwardsMappingData1_19_3() {
super("1.19.3", "1.19", Protocol1_19_1To1_19_3.class);
mappedSounds.defaultReturnValue(-1);
}
@Override
protected void loadExtras(final CompoundTag data) {
super.loadExtras(data);
final JsonArray sounds = BackwardsMappingDataLoader.INSTANCE.loadData("sounds-1.19.json").getAsJsonArray("sounds");
int i = 0;
for (final JsonElement sound : sounds) {
mappedSounds.put(sound.getAsString(), i++);
}
}
public int mappedSound(final String sound) {
return mappedSounds.getInt(Key.stripMinecraftNamespace(sound));
}
}
@@ -71,6 +71,7 @@ public final class Protocol1_19_4To1_19_3 extends BackwardsProtocol<ClientboundP
translatableRewriter.registerComponentPacket(ClientboundPackets1_19_4.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_19_4.TAB_LIST);
translatableRewriter.registerPlayerCombatKill(ClientboundPackets1_19_4.PLAYER_COMBAT_KILL);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_19_4.SET_PLAYER_TEAM);
translatableRewriter.registerComponentPacket(ClientboundPackets1_19_4.SYSTEM_CHAT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_19_4.DISGUISED_CHAT);
translatableRewriter.registerPing();
@@ -45,6 +45,8 @@ import com.viaversion.viaversion.util.TagUtil;
public final class EntityPacketRewriter1_19_4 extends EntityRewriter<ClientboundPackets1_19_4, Protocol1_19_4To1_19_3> {
private static final double TEXT_DISPLAY_Y_OFFSET = -0.25; // Move emulated armor stands down to match text display height offsets
public EntityPacketRewriter1_19_4(final Protocol1_19_4To1_19_3 protocol) {
super(protocol, Types1_19_3.ENTITY_DATA_TYPES.optionalComponentType, Types1_19_3.ENTITY_DATA_TYPES.booleanType);
}
@@ -78,6 +80,11 @@ public final class EntityPacketRewriter1_19_4 extends EntityRewriter<Clientbound
}
}
final double y = wrapper.get(Types.DOUBLE, 1);
if (entityType == EntityTypes1_19_4.TEXT_DISPLAY.getId()) {
wrapper.set(Types.DOUBLE, 1, y + TEXT_DISPLAY_Y_OFFSET);
}
// First track (and remap) entity, then put storage for block display entity
getSpawnTrackerWithDataHandler1_19(EntityTypes1_19_4.FALLING_BLOCK).handle(wrapper);
if (entityType != EntityTypes1_19_4.BLOCK_DISPLAY.getId()) {
@@ -88,7 +95,6 @@ public final class EntityPacketRewriter1_19_4 extends EntityRewriter<Clientbound
if (data != null) {
final LinkedEntityStorage storage = new LinkedEntityStorage();
final double x = wrapper.get(Types.DOUBLE, 0);
final double y = wrapper.get(Types.DOUBLE, 1);
final double z = wrapper.get(Types.DOUBLE, 2);
storage.setPosition(x, y, z);
data.put(storage);
@@ -183,7 +189,7 @@ public final class EntityPacketRewriter1_19_4 extends EntityRewriter<Clientbound
wrapper.passthrough(Types.VAR_INT); // Effect id
wrapper.passthrough(Types.BYTE); // Amplifier
// Handle inifinite duration. Use a value the client still accepts without bugging out the display while still being practically infinite
// Handle infinite duration. Use a value the client still accepts without bugging out the display while still being practically infinite
final int duration = wrapper.read(Types.VAR_INT);
wrapper.write(Types.VAR_INT, duration == -1 ? 999999 : duration);
});
@@ -198,11 +204,14 @@ public final class EntityPacketRewriter1_19_4 extends EntityRewriter<Clientbound
final double z = wrapper.passthrough(Types.DOUBLE);
final EntityTracker1_19_4 tracker = tracker(wrapper.user());
final LinkedEntityStorage storage = tracker.linkedEntityStorage(entityId);
if (storage == null) {
return;
if (tracker.entityType(entityId) == EntityTypes1_19_4.TEXT_DISPLAY) {
wrapper.set(Types.DOUBLE, 1, y + TEXT_DISPLAY_Y_OFFSET);
}
final LinkedEntityStorage storage = tracker.linkedEntityStorage(entityId);
if (storage != null) {
storage.setPosition(x, y, z);
}
storage.setPosition(x, y, z);
});
final PacketHandler entityPositionHandler = wrapper -> {
@@ -213,10 +222,9 @@ public final class EntityPacketRewriter1_19_4 extends EntityRewriter<Clientbound
final EntityTracker1_19_4 tracker = tracker(wrapper.user());
final LinkedEntityStorage storage = tracker.linkedEntityStorage(entityId);
if (storage == null) {
return;
if (storage != null) {
storage.addRelativePosition(x, y, z);
}
storage.addRelativePosition(x, y, z);
};
protocol.registerClientbound(ClientboundPackets1_19_4.MOVE_ENTITY_POS, entityPositionHandler);
@@ -86,6 +86,7 @@ public final class Protocol1_19To1_18_2 extends BackwardsProtocol<ClientboundPac
translatableRewriter.registerBossEvent(ClientboundPackets1_19.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_19.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_19.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_19.SET_PLAYER_TEAM);
translatableRewriter.registerOpenScreen1_14(ClientboundPackets1_19.OPEN_SCREEN);
translatableRewriter.registerPlayerCombatKill(ClientboundPackets1_19.PLAYER_COMBAT_KILL);
translatableRewriter.registerPing();
@@ -111,6 +111,7 @@ public final class Protocol1_20_5To1_20_3 extends BackwardsProtocol<ClientboundP
translatableRewriter.registerBossEvent(ClientboundPackets1_20_5.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_20_5.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_20_5.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_20_5.SET_PLAYER_TEAM);
translatableRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_20_5.PLAYER_COMBAT_KILL);
translatableRewriter.registerComponentPacket(ClientboundPackets1_20_5.SYSTEM_CHAT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_20_5.DISGUISED_CHAT);
@@ -71,6 +71,7 @@ public final class Protocol1_20To1_19_4 extends BackwardsProtocol<ClientboundPac
translatableRewriter.registerBossEvent(ClientboundPackets1_19_4.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_19_4.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_19_4.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_19_4.SET_PLAYER_TEAM);
translatableRewriter.registerComponentPacket(ClientboundPackets1_19_4.SYSTEM_CHAT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_19_4.DISGUISED_CHAT);
translatableRewriter.registerPing();
@@ -0,0 +1,251 @@
/*
* 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_11to1_21_9;
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.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
import com.viaversion.viabackwards.api.rewriters.BackwardsRegistryRewriter;
import com.viaversion.viabackwards.api.rewriters.SoundRewriter;
import com.viaversion.viabackwards.api.rewriters.text.NBTComponentRewriter;
import com.viaversion.viabackwards.protocol.v1_21_11to1_21_9.rewriter.BlockItemPacketRewriter1_21_11;
import com.viaversion.viabackwards.protocol.v1_21_11to1_21_9.rewriter.ComponentRewriter1_21_11;
import com.viaversion.viabackwards.protocol.v1_21_11to1_21_9.rewriter.EntityPacketRewriter1_21_11;
import com.viaversion.viabackwards.protocol.v1_21_11to1_21_9.storage.GameTimeStorage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_11;
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.VersionedTypes;
import com.viaversion.viaversion.api.type.types.version.VersionedTypesHolder;
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.ServerboundPackets1_21_6;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundConfigurationPackets1_21_9;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundPacket1_21_9;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundPackets1_21_9;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ServerboundConfigurationPackets1_21_9;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ServerboundPacket1_21_9;
import com.viaversion.viaversion.protocols.v1_21_9to1_21_11.Protocol1_21_9To1_21_11;
import com.viaversion.viaversion.protocols.v1_21_9to1_21_11.packet.ClientboundPacket1_21_11;
import com.viaversion.viaversion.protocols.v1_21_9to1_21_11.packet.ClientboundPackets1_21_11;
import com.viaversion.viaversion.rewriter.AttributeRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.TagUtil;
import java.util.function.Function;
import org.checkerframework.checker.nullness.qual.Nullable;
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
import static com.viaversion.viaversion.util.TagUtil.getNamespacedTag;
public final class Protocol1_21_11To1_21_9 extends BackwardsProtocol<ClientboundPacket1_21_11, ClientboundPacket1_21_9, ServerboundPacket1_21_9, ServerboundPacket1_21_9> {
public static final BackwardsMappingData MAPPINGS = new BackwardsMappingData("1.21.11", "1.21.9", Protocol1_21_9To1_21_11.class);
private static final int END_FOG_COLOR = 10518688;
private static final int OVERWORLD_FOG_COLOR = 126384063;
private final EntityPacketRewriter1_21_11 entityRewriter = new EntityPacketRewriter1_21_11(this);
private final BlockItemPacketRewriter1_21_11 itemRewriter = new BlockItemPacketRewriter1_21_11(this);
private final ParticleRewriter<ClientboundPacket1_21_11> particleRewriter = new ParticleRewriter<>(this);
private final NBTComponentRewriter<ClientboundPacket1_21_11> translatableRewriter = new ComponentRewriter1_21_11(this);
private final TagRewriter<ClientboundPacket1_21_11> tagRewriter = new TagRewriter<>(this);
private final RegistryDataRewriter registryDataRewriter = new BackwardsRegistryRewriter(this);
public Protocol1_21_11To1_21_9() {
super(ClientboundPacket1_21_11.class, ClientboundPacket1_21_9.class, ServerboundPacket1_21_9.class, ServerboundPacket1_21_9.class);
}
private void moveAttribute(final CompoundTag baseTag, @Nullable final CompoundTag attributes, final String key, final String mappedKey, final Function<Tag, Tag> tagMapper, @Nullable final Tag defaultTag) {
final Tag attributeTag;
if (attributes != null && (attributeTag = getNamespacedTag(attributes, key)) != null) {
baseTag.put(mappedKey, tagMapper.apply(attributeTag));
} else if (defaultTag != null) {
baseTag.put(mappedKey, defaultTag);
}
}
private int floatsToARGB(final float r, final float g, final float b) {
return 255 << 24 | (int) (r * 255) << 16 | (int) (g * 255) << 8 | (int) (b * 255);
}
@Override
protected void registerPackets() {
super.registerPackets();
// Add back mandatory fields from attributes, though most don't have any use in the client
registryDataRewriter.addHandler("dimension_type", (key, tag) -> {
if (Key.equals(key, "the_nether")) {
tag.putString("effects", "minecraft:the_nether");
tag.putBoolean("natural", false);
} else if (Key.equals(key, "the_end")) {
tag.putString("effects", "minecraft:the_end");
tag.putBoolean("natural", false);
} else {
tag.putString("effects", "minecraft:overworld");
tag.putBoolean("natural", true);
}
final ByteTag trueTag = new ByteTag((byte) 1);
final CompoundTag attributes = tag.getCompoundTag("attributes");
moveAttribute(tag, attributes, "visual/cloud_height", "cloud_height", Function.identity(), null);
moveAttribute(tag, attributes, "gameplay/can_start_raid", "has_raids", Function.identity(), trueTag);
moveAttribute(tag, attributes, "gameplay/can_start_raid", "has_raids", Function.identity(), trueTag);
moveAttribute(tag, attributes, "gameplay/piglins_zombify", "piglin_safe", attributeTag -> ((NumberTag) attributeTag).asBoolean() ? ByteTag.ZERO : trueTag, ByteTag.ZERO);
moveAttribute(tag, attributes, "gameplay/respawn_anchor_works", "respawn_anchor_works", Function.identity(), trueTag);
moveAttribute(tag, attributes, "gameplay/bed_rule", "bed_works", attributeTag -> {
final CompoundTag bedRule = (CompoundTag) attributeTag;
return bedRule.getBoolean("can_sleep") || bedRule.getBoolean("can_set_spawn") ? trueTag : ByteTag.ZERO;
}, trueTag);
// Many different functions back into one, all have different effects on the client, so pick the most important one...
moveAttribute(tag, attributes, "gameplay/fast_lava", "ultrawarm", Function.identity(), ByteTag.ZERO);
});
registryDataRewriter.addHandler("worldgen/biome", (key, tag) -> {
final CompoundTag effects = tag.getCompoundTag("effects");
final CompoundTag attributes = tag.removeUnchecked("attributes");
moveAttribute(effects, attributes, "visual/sky_color", "sky_color", this::mapColor, new IntTag(0));
moveAttribute(effects, attributes, "visual/water_fog_color", "water_fog_color", this::mapColor, new IntTag(-16448205));
moveAttribute(effects, attributes, "visual/fog_color", "fog_color", this::mapColor, new IntTag(Key.equals(key, "the_end") ? END_FOG_COLOR : OVERWORLD_FOG_COLOR)); // overworld fog color as default
moveAttribute(effects, effects, "water_color", "water_color", this::mapColor, new IntTag(4159204));
moveAttribute(effects, effects, "foliage_color", "foliage_color", this::mapColor, null);
moveAttribute(effects, effects, "dry_foliage_color", "dry_foliage_color", this::mapColor, null);
moveAttribute(effects, effects, "grass_color", "grass_color", this::mapColor, null);
});
registryDataRewriter.addHandler("enchantment", (key, tag) -> {
final CompoundTag effects = tag.getCompoundTag("effects");
if (effects != null) {
TagUtil.removeNamespaced(effects, "post_piercing_attack");
}
});
registerClientbound(ClientboundConfigurationPackets1_21_9.REGISTRY_DATA, registryDataRewriter::handle);
tagRewriter.removeTags("timeline");
tagRewriter.registerGeneric(ClientboundPackets1_21_11.UPDATE_TAGS);
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21_9.UPDATE_TAGS);
final SoundRewriter<ClientboundPacket1_21_11> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound1_19_3(ClientboundPackets1_21_11.SOUND);
soundRewriter.registerSound1_19_3(ClientboundPackets1_21_11.SOUND_ENTITY);
soundRewriter.registerStopSound(ClientboundPackets1_21_11.STOP_SOUND);
new StatisticsRewriter<>(this).register(ClientboundPackets1_21_11.AWARD_STATS);
new AttributeRewriter<>(this).register1_21(ClientboundPackets1_21_11.UPDATE_ATTRIBUTES);
translatableRewriter.registerOpenScreen1_14(ClientboundPackets1_21_11.OPEN_SCREEN);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_11.SET_ACTION_BAR_TEXT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_11.SET_TITLE_TEXT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_11.SET_SUBTITLE_TEXT);
translatableRewriter.registerBossEvent(ClientboundPackets1_21_11.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_11.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_21_11.TAB_LIST);
translatableRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21_11.PLAYER_COMBAT_KILL);
translatableRewriter.registerPlayerInfoUpdate1_21_4(ClientboundPackets1_21_11.PLAYER_INFO_UPDATE);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_11.SYSTEM_CHAT);
translatableRewriter.registerDisguisedChat(ClientboundPackets1_21_11.DISGUISED_CHAT);
translatableRewriter.registerPlayerChat1_21_5(ClientboundPackets1_21_11.PLAYER_CHAT);
translatableRewriter.registerPing();
particleRewriter.registerLevelParticles1_21_4(ClientboundPackets1_21_11.LEVEL_PARTICLES);
particleRewriter.registerExplode1_21_9(ClientboundPackets1_21_11.EXPLODE);
}
@Override
public void init(final UserConnection connection) {
addEntityTracker(connection, new EntityTrackerBase(connection, EntityTypes1_21_11.PLAYER));
addItemHasher(connection, new ItemHasherBase(this, connection));
connection.put(new GameTimeStorage());
}
@Override
public BackwardsMappingData getMappingData() {
return MAPPINGS;
}
@Override
public EntityPacketRewriter1_21_11 getEntityRewriter() {
return entityRewriter;
}
@Override
public BlockItemPacketRewriter1_21_11 getItemRewriter() {
return itemRewriter;
}
@Override
public RegistryDataRewriter getRegistryDataRewriter() {
return registryDataRewriter;
}
@Override
public ParticleRewriter<ClientboundPacket1_21_11> getParticleRewriter() {
return particleRewriter;
}
@Override
public NBTComponentRewriter<ClientboundPacket1_21_11> getComponentRewriter() {
return translatableRewriter;
}
@Override
public TagRewriter<ClientboundPacket1_21_11> getTagRewriter() {
return tagRewriter;
}
@Override
public VersionedTypesHolder types() {
return VersionedTypes.V1_21_11;
}
@Override
public VersionedTypesHolder mappedTypes() {
return VersionedTypes.V1_21_9;
}
@Override
protected PacketTypesProvider<ClientboundPacket1_21_11, ClientboundPacket1_21_9, ServerboundPacket1_21_9, ServerboundPacket1_21_9> createPacketTypesProvider() {
return new SimplePacketTypesProvider<>(
packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_21_11.class, ClientboundConfigurationPackets1_21_9.class),
packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_21_9.class, ClientboundConfigurationPackets1_21_9.class),
packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_21_6.class, ServerboundConfigurationPackets1_21_9.class),
packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_21_6.class, ServerboundConfigurationPackets1_21_9.class)
);
}
private Tag mapColor(final Tag attributeTag) {
if (attributeTag instanceof ListTag<?> listTag) {
final NumberTag r = ((NumberTag) listTag.get(0));
final NumberTag g = ((NumberTag) listTag.get(1));
final NumberTag b = ((NumberTag) listTag.get(2));
return new IntTag(floatsToARGB(r.asFloat(), g.asFloat(), b.asFloat()));
} else if (attributeTag instanceof StringTag stringTag) {
// Remove '#' and parse hex string
return new IntTag(Integer.parseInt(stringTag.getValue().substring(1), 16));
}
return attributeTag;
}
}
@@ -0,0 +1,295 @@
/*
* 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_11to1_21_9.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.IntTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viabackwards.api.rewriters.BackwardsStructuredItemRewriter;
import com.viaversion.viabackwards.protocol.v1_21_11to1_21_9.Protocol1_21_11To1_21_9;
import com.viaversion.viabackwards.protocol.v1_21_11to1_21_9.storage.GameTimeStorage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Holder;
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.AttackRange;
import com.viaversion.viaversion.api.minecraft.item.data.DamageType;
import com.viaversion.viaversion.api.minecraft.item.data.KineticWeapon;
import com.viaversion.viaversion.api.minecraft.item.data.PiercingWeapon;
import com.viaversion.viaversion.api.minecraft.item.data.SwingAnimation;
import com.viaversion.viaversion.api.minecraft.item.data.UseEffects;
import com.viaversion.viaversion.api.type.Types;
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.ServerboundPackets1_21_6;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ServerboundPacket1_21_9;
import com.viaversion.viaversion.protocols.v1_21_9to1_21_11.packet.ClientboundPacket1_21_11;
import com.viaversion.viaversion.protocols.v1_21_9to1_21_11.packet.ClientboundPackets1_21_11;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
import com.viaversion.viaversion.util.Either;
import org.checkerframework.checker.nullness.qual.Nullable;
import static com.viaversion.viaversion.protocols.v1_21_9to1_21_11.rewriter.BlockItemPacketRewriter1_21_11.downgradeData;
import static com.viaversion.viaversion.protocols.v1_21_9to1_21_11.rewriter.BlockItemPacketRewriter1_21_11.upgradeData;
public final class BlockItemPacketRewriter1_21_11 extends BackwardsStructuredItemRewriter<ClientboundPacket1_21_11, ServerboundPacket1_21_9, Protocol1_21_11To1_21_9> {
public BlockItemPacketRewriter1_21_11(final Protocol1_21_11To1_21_9 protocol) {
super(protocol);
}
@Override
public void registerPackets() {
final BlockRewriter<ClientboundPacket1_21_11> blockRewriter = BlockRewriter.for1_20_2(protocol);
blockRewriter.registerBlockEvent(ClientboundPackets1_21_11.BLOCK_EVENT);
blockRewriter.registerBlockUpdate(ClientboundPackets1_21_11.BLOCK_UPDATE);
blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21_11.SECTION_BLOCKS_UPDATE);
blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21_11.LEVEL_EVENT, 2001);
blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21_11.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_21_5::new);
blockRewriter.registerBlockEntityData(ClientboundPackets1_21_11.BLOCK_ENTITY_DATA);
registerSetCursorItem(ClientboundPackets1_21_11.SET_CURSOR_ITEM);
registerSetPlayerInventory(ClientboundPackets1_21_11.SET_PLAYER_INVENTORY);
registerCooldown1_21_2(ClientboundPackets1_21_11.COOLDOWN);
registerSetContent1_21_2(ClientboundPackets1_21_11.CONTAINER_SET_CONTENT);
registerSetSlot1_21_2(ClientboundPackets1_21_11.CONTAINER_SET_SLOT);
registerAdvancements1_20_3(ClientboundPackets1_21_11.UPDATE_ADVANCEMENTS);
registerSetEquipment(ClientboundPackets1_21_11.SET_EQUIPMENT);
registerMerchantOffers1_20_5(ClientboundPackets1_21_11.MERCHANT_OFFERS);
registerContainerClick1_21_5(ServerboundPackets1_21_6.CONTAINER_CLICK);
registerSetCreativeModeSlot1_21_5(ServerboundPackets1_21_6.SET_CREATIVE_MODE_SLOT);
final RecipeDisplayRewriter<ClientboundPacket1_21_11> recipeRewriter = new RecipeDisplayRewriter1_21_5<>(protocol);
recipeRewriter.registerUpdateRecipes(ClientboundPackets1_21_11.UPDATE_RECIPES);
recipeRewriter.registerRecipeBookAdd(ClientboundPackets1_21_11.RECIPE_BOOK_ADD);
recipeRewriter.registerPlaceGhostRecipe(ClientboundPackets1_21_11.PLACE_GHOST_RECIPE);
protocol.registerClientbound(ClientboundPackets1_21_11.SET_TIME, wrapper -> {
final long gameTime = wrapper.passthrough(Types.LONG);
wrapper.user().get(GameTimeStorage.class).setGameTime(gameTime);
});
protocol.registerServerbound(ServerboundPackets1_21_6.CLIENT_TICK_END, wrapper -> {
wrapper.user().get(GameTimeStorage.class).incrementGameTime();
});
}
@Override
protected void handleItemDataComponentsToClient(final UserConnection connection, final Item item, final StructuredDataContainer container) {
super.handleItemDataComponentsToClient(connection, item, container);
downgradeData(item, container);
}
@Override
protected void handleItemDataComponentsToServer(final UserConnection connection, final Item item, final StructuredDataContainer container) {
super.handleItemDataComponentsToServer(connection, item, container);
upgradeData(item, container);
}
@Override
protected void restoreBackupData(final Item item, final StructuredDataContainer container, final CompoundTag customData) {
super.restoreBackupData(item, container, customData);
if (!(customData.remove(nbtTagName("backup")) instanceof final CompoundTag backupTag)) {
return;
}
final CompoundTag swingTag = backupTag.getCompoundTag("swing_animation");
if (swingTag != null) {
final int type = swingTag.getInt("type");
final int duration = swingTag.getInt("duration");
container.set(StructuredDataKey.SWING_ANIMATION, new SwingAnimation(type, duration));
}
final CompoundTag kineticTag = backupTag.getCompoundTag("kinetic_weapon");
if (kineticTag != null) {
final int contactCooldownTicks = kineticTag.getInt("contact_cooldown_ticks");
final int delayTicks = kineticTag.getInt("delay_ticks");
final KineticWeapon.Condition damageConditions = loadDamageCondition(kineticTag, "damage_conditions");
final KineticWeapon.Condition dismountConditions = loadDamageCondition(kineticTag, "dismount_conditions");
final KineticWeapon.Condition knockbackConditions = loadDamageCondition(kineticTag, "knockback_conditions");
final float forwardMovement = kineticTag.getFloat("forward_movement");
final float damageMultiplier = kineticTag.getFloat("damage_multiplier");
final Holder<SoundEvent> sound = kineticTag.contains("sound") ? restoreSoundEventHolder(kineticTag, "sound") : null;
final Holder<SoundEvent> hitSound = kineticTag.contains("hit_sound") ? restoreSoundEventHolder(kineticTag, "hit_sound") : null;
container.set(StructuredDataKey.KINETIC_WEAPON, new KineticWeapon(contactCooldownTicks, delayTicks, damageConditions, dismountConditions, knockbackConditions, forwardMovement, damageMultiplier, sound, hitSound));
}
final CompoundTag piercingTag = backupTag.getCompoundTag("piercing_weapon");
if (piercingTag != null) {
final boolean dealsKnockback = piercingTag.getBoolean("deals_knockback");
final boolean dismounts = piercingTag.getBoolean("dismounts");
final Holder<SoundEvent> sound = piercingTag.contains("sound") ? restoreSoundEventHolder(piercingTag, "sound") : null;
final Holder<SoundEvent> hitSound = piercingTag.contains("hit_sound") ? restoreSoundEventHolder(piercingTag, "hit_sound") : null;
container.set(StructuredDataKey.PIERCING_WEAPON, new PiercingWeapon(dealsKnockback, dismounts, sound, hitSound));
}
final Tag damageTypeId = backupTag.get("damage_type_id");
if (damageTypeId != null) {
if (damageTypeId instanceof StringTag stringTag) {
container.set(StructuredDataKey.DAMAGE_TYPE, new DamageType(Either.right(stringTag.getValue())));
} else if (damageTypeId instanceof IntTag intTag) {
container.set(StructuredDataKey.DAMAGE_TYPE, new DamageType(Either.left(intTag.asInt())));
}
}
final CompoundTag useEffectsTag = backupTag.getCompoundTag("use_effects");
if (useEffectsTag != null) {
final boolean canSprint = useEffectsTag.getBoolean("can_sprint");
final boolean interactVibrations = useEffectsTag.getBoolean("interact_vibrations");
final float speedMultiplier = useEffectsTag.getFloat("speed_multiplier");
container.set(StructuredDataKey.USE_EFFECTS, new UseEffects(canSprint, interactVibrations, speedMultiplier));
}
final CompoundTag attackRangeTag = backupTag.getCompoundTag("attack_range");
if (attackRangeTag != null) {
final float minRange = attackRangeTag.getFloat("min_range");
final float maxRange = attackRangeTag.getFloat("max_range");
final float minCreativeRange = attackRangeTag.getFloat("min_creative_reach");
final float maxCreativeRange = attackRangeTag.getFloat("max_creative_reach");
final float hitboxMargin = attackRangeTag.getFloat("hitbox_margin");
final float mobFactor = attackRangeTag.getFloat("mob_factor");
container.set(StructuredDataKey.ATTACK_RANGE, new AttackRange(minRange, maxRange, minCreativeRange, maxCreativeRange, hitboxMargin, mobFactor));
}
final Tag zombieNautilusVariantTag = backupTag.get("zombie_nautilus_variant");
if (zombieNautilusVariantTag != null) {
if (zombieNautilusVariantTag instanceof StringTag stringTag) {
container.set(StructuredDataKey.ZOMBIE_NAUTILUS_VARIANT, Either.right(stringTag.getValue()));
} else if (zombieNautilusVariantTag instanceof IntTag intTag) {
container.set(StructuredDataKey.ZOMBIE_NAUTILUS_VARIANT, Either.left(intTag.asInt()));
}
}
restoreFloatData(StructuredDataKey.MINIMUM_ATTACK_CHARGE, container, backupTag);
}
private KineticWeapon.Condition loadDamageCondition(final CompoundTag tag, final String key) {
final CompoundTag conditionTag = tag.getCompoundTag(key);
if (conditionTag == null) {
return null;
}
final int maxDurationTicks = conditionTag.getInt("max_duration_ticks");
final float minSpeed = conditionTag.getFloat("min_speed");
final float minRelativeSpeed = conditionTag.getFloat("min_relative_speed");
return new KineticWeapon.Condition(maxDurationTicks, minSpeed, minRelativeSpeed);
}
@Override
protected void backupInconvertibleData(final UserConnection connection, final Item item, final StructuredDataContainer dataContainer, final CompoundTag backupTag) {
super.backupInconvertibleData(connection, item, dataContainer, backupTag);
final SwingAnimation swingAnimation = dataContainer.get(StructuredDataKey.SWING_ANIMATION);
if (swingAnimation != null) {
final CompoundTag swingTag = new CompoundTag();
swingTag.putInt("type", swingAnimation.type());
swingTag.putInt("duration", swingAnimation.duration());
backupTag.put("swing_animation", swingTag);
}
final KineticWeapon kineticWeapon = dataContainer.get(StructuredDataKey.KINETIC_WEAPON);
if (kineticWeapon != null) {
final CompoundTag kineticTag = new CompoundTag();
kineticTag.putInt("contact_cooldown_ticks", kineticWeapon.contactCooldownTicks());
kineticTag.putInt("delay_ticks", kineticWeapon.delayTicks());
saveDamageCondition(kineticTag, "damage_conditions", kineticWeapon.damageConditions());
saveDamageCondition(kineticTag, "dismount_conditions", kineticWeapon.dismountConditions());
saveDamageCondition(kineticTag, "knockback_conditions", kineticWeapon.knockbackConditions());
kineticTag.putFloat("forward_movement", kineticWeapon.forwardMovement());
kineticTag.putFloat("damage_multiplier", kineticWeapon.damageMultiplier());
if (kineticWeapon.sound() != null) {
kineticTag.put("sound", holderToTag(kineticWeapon.sound(), this::saveSoundEvent));
}
if (kineticWeapon.hitSound() != null) {
kineticTag.put("hit_sound", holderToTag(kineticWeapon.hitSound(), this::saveSoundEvent));
}
backupTag.put("kinetic_weapon", kineticTag);
}
final PiercingWeapon piercingWeapon = dataContainer.get(StructuredDataKey.PIERCING_WEAPON);
if (piercingWeapon != null) {
final CompoundTag piercingTag = new CompoundTag();
piercingTag.putBoolean("deals_knockback", piercingWeapon.dealsKnockback());
piercingTag.putBoolean("dismounts", piercingWeapon.dismounts());
if (piercingWeapon.sound() != null) {
piercingTag.put("sound", holderToTag(piercingWeapon.sound(), this::saveSoundEvent));
}
if (piercingWeapon.hitSound() != null) {
piercingTag.put("hit_sound", holderToTag(piercingWeapon.hitSound(), this::saveSoundEvent));
}
backupTag.put("piercing_weapon", piercingTag);
}
final DamageType damageType = dataContainer.get(StructuredDataKey.DAMAGE_TYPE);
if (damageType != null) {
if (damageType.id().isLeft()) {
backupTag.putInt("damage_type_id", damageType.id().left());
} else {
backupTag.putString("damage_type_id", damageType.id().right());
}
}
final UseEffects useEffects = dataContainer.get(StructuredDataKey.USE_EFFECTS);
if (useEffects != null) {
final CompoundTag useEffectsTag = new CompoundTag();
useEffectsTag.putBoolean("can_sprint", useEffects.canSprint());
useEffectsTag.putBoolean("interact_vibrations", useEffects.interactVibrations());
useEffectsTag.putFloat("speed_multiplier", useEffects.speedMultiplier());
backupTag.put("use_effects", useEffectsTag);
}
final AttackRange attackRange = dataContainer.get(StructuredDataKey.ATTACK_RANGE);
if (attackRange != null) {
final CompoundTag attackRangeTag = new CompoundTag();
attackRangeTag.putFloat("min_range", attackRange.minRange());
attackRangeTag.putFloat("max_range", attackRange.maxRange());
attackRangeTag.putFloat("min_creative_reach", attackRange.minCreativeRange());
attackRangeTag.putFloat("max_creative_reach", attackRange.maxCreativeRange());
attackRangeTag.putFloat("hitbox_margin", attackRange.hitboxMargin());
attackRangeTag.putFloat("mob_factor", attackRange.mobFactor());
backupTag.put("attack_range", attackRangeTag);
}
final Either<Integer, String> zombieNautilusVariant = dataContainer.get(StructuredDataKey.ZOMBIE_NAUTILUS_VARIANT);
if (zombieNautilusVariant != null) {
if (zombieNautilusVariant.isLeft()) {
backupTag.putInt("zombie_nautilus_variant", zombieNautilusVariant.left());
} else {
backupTag.putString("zombie_nautilus_variant", zombieNautilusVariant.right());
}
}
saveFloatData(StructuredDataKey.MINIMUM_ATTACK_CHARGE, dataContainer, backupTag);
}
private void saveDamageCondition(final CompoundTag tag, final String key, final KineticWeapon.@Nullable Condition condition) {
if (condition == null) {
return;
}
final CompoundTag conditionTag = new CompoundTag();
conditionTag.putInt("max_duration_ticks", condition.maxDurationTicks());
conditionTag.putFloat("min_speed", condition.minSpeed());
conditionTag.putFloat("min_relative_speed", condition.minRelativeSpeed());
tag.put(key, conditionTag);
}
}
@@ -0,0 +1,43 @@
/*
* 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_11to1_21_9.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.rewriters.text.NBTComponentRewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.protocols.v1_21_9to1_21_11.packet.ClientboundPacket1_21_11;
public final class ComponentRewriter1_21_11 extends NBTComponentRewriter<ClientboundPacket1_21_11> {
public ComponentRewriter1_21_11(final BackwardsProtocol<ClientboundPacket1_21_11, ?, ?, ?> protocol) {
super(protocol);
}
@Override
protected void handleShowItem(final UserConnection connection, final CompoundTag itemTag, final CompoundTag componentsTag) {
super.handleShowItem(connection, itemTag, componentsTag);
if (componentsTag == null) {
return;
}
removeDataComponents(componentsTag, StructuredDataKey.SWING_ANIMATION, StructuredDataKey.KINETIC_WEAPON, StructuredDataKey.PIERCING_WEAPON,
StructuredDataKey.DAMAGE_TYPE, StructuredDataKey.MINIMUM_ATTACK_CHARGE, StructuredDataKey.USE_EFFECTS, StructuredDataKey.ZOMBIE_NAUTILUS_VARIANT, StructuredDataKey.ATTACK_RANGE);
}
}
@@ -0,0 +1,107 @@
/*
* 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_11to1_21_9.rewriter;
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
import com.viaversion.viabackwards.protocol.v1_21_11to1_21_9.Protocol1_21_11To1_21_9;
import com.viaversion.viabackwards.protocol.v1_21_11to1_21_9.storage.GameTimeStorage;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_11;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21_11;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21_9;
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundPackets1_21_9;
import com.viaversion.viaversion.protocols.v1_21_9to1_21_11.packet.ClientboundPacket1_21_11;
import com.viaversion.viaversion.protocols.v1_21_9to1_21_11.packet.ClientboundPackets1_21_11;
import com.viaversion.viaversion.rewriter.entitydata.EntityDataHandlerEvent;
public final class EntityPacketRewriter1_21_11 extends EntityRewriter<ClientboundPacket1_21_11, Protocol1_21_11To1_21_9> {
public EntityPacketRewriter1_21_11(final Protocol1_21_11To1_21_9 protocol) {
super(protocol, VersionedTypes.V1_21_9.entityDataTypes.optionalComponentType, VersionedTypes.V1_21_9.entityDataTypes.booleanType);
}
@Override
public void registerPackets() {
registerTrackerWithData1_21_9(ClientboundPackets1_21_11.ADD_ENTITY, EntityTypes1_21_11.FALLING_BLOCK);
registerSetEntityData(ClientboundPackets1_21_11.SET_ENTITY_DATA);
registerRemoveEntities(ClientboundPackets1_21_11.REMOVE_ENTITIES);
registerPlayerAbilities(ClientboundPackets1_21_11.PLAYER_ABILITIES);
registerGameEvent(ClientboundPackets1_21_11.GAME_EVENT);
registerLogin1_20_5(ClientboundPackets1_21_11.LOGIN);
registerRespawn1_20_5(ClientboundPackets1_21_11.RESPAWN);
protocol.registerClientbound(ClientboundPackets1_21_11.MOUNT_SCREEN_OPEN, ClientboundPackets1_21_9.HORSE_SCREEN_OPEN);
}
@Override
protected void registerRewrites() {
final EntityDataTypes1_21_11 unmappedDataTypes = VersionedTypes.V1_21_11.entityDataTypes;
final EntityDataTypes1_21_9 entityDataTypes = VersionedTypes.V1_21_9.entityDataTypes;
filter().mapDataType(id -> {
if (id == unmappedDataTypes.humanoidArmType.typeId() || id == unmappedDataTypes.zombieNautilusVariantType.typeId()) {
return null;
}
if (id > unmappedDataTypes.zombieNautilusVariantType.typeId()) {
id--;
}
return entityDataTypes.byId(id);
});
registerEntityDataTypeHandler1_20_3(
entityDataTypes.itemType,
entityDataTypes.blockStateType,
entityDataTypes.optionalBlockStateType,
entityDataTypes.particleType,
entityDataTypes.particlesType,
entityDataTypes.componentType,
entityDataTypes.optionalComponentType
);
filter().type(EntityTypes1_21_11.AVATAR).index(15).handler(((event, data) -> {
final int arm = data.value();
data.setTypeAndValue(entityDataTypes.byteType, (byte) arm);
}));
filter().type(EntityTypes1_21_11.WOLF).index(21).handler(this::absoluteToRelativeTicks);
filter().type(EntityTypes1_21_11.BEE).index(18).handler(this::absoluteToRelativeTicks);
filter().type(EntityTypes1_21_11.ABSTRACT_NAUTILUS).removeIndex(19); // Dashing
filter().type(EntityTypes1_21_11.ZOMBIE_NAUTILUS).removeIndex(20); // Variant
}
private void absoluteToRelativeTicks(final EntityDataHandlerEvent event, final EntityData data) {
final long currentGameTime = event.user().get(GameTimeStorage.class).gameTime();
final long angerEndTime = data.value();
final int angerEndIn = Math.toIntExact(angerEndTime - currentGameTime);
data.setTypeAndValue(VersionedTypes.V1_21_9.entityDataTypes.varIntType, Math.max(angerEndIn, 0));
}
@Override
public void onMappingDataLoaded() {
mapTypes();
mapEntityTypeWithData(EntityTypes1_21_11.NAUTILUS, EntityTypes1_21_11.SQUID).tagName();
mapEntityTypeWithData(EntityTypes1_21_11.ZOMBIE_NAUTILUS, EntityTypes1_21_11.GLOW_SQUID).tagName();
mapEntityTypeWithData(EntityTypes1_21_11.CAMEL_HUSK, EntityTypes1_21_11.CAMEL).tagName();
mapEntityTypeWithData(EntityTypes1_21_11.PARCHED, EntityTypes1_21_11.SKELETON).tagName();
}
@Override
public EntityType typeFromId(final int type) {
return EntityTypes1_21_11.getTypeFromId(type);
}
}
@@ -0,0 +1,37 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* 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_11to1_21_9.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
public final class GameTimeStorage implements StorableObject {
private long gameTime;
public long gameTime() {
return gameTime;
}
public void setGameTime(final long gameTime) {
this.gameTime = gameTime;
}
public void incrementGameTime() {
gameTime++;
}
}
@@ -29,6 +29,7 @@ import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.InventoryState
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.ItemTagStorage;
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.PlayerStorage;
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.RecipeStorage;
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.SignStorage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_5;
import com.viaversion.viaversion.api.minecraft.item.data.ChatType;
@@ -95,6 +96,7 @@ public final class Protocol1_21_2To1_21 extends BackwardsProtocol<ClientboundPac
translatableRewriter.registerBossEvent(ClientboundPackets1_21_2.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_21_2.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_21_2.SET_PLAYER_TEAM);
translatableRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21_2.PLAYER_COMBAT_KILL);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.SYSTEM_CHAT);
translatableRewriter.registerDisguisedChat(ClientboundPackets1_21_2.DISGUISED_CHAT);
@@ -159,6 +161,7 @@ public final class Protocol1_21_2To1_21 extends BackwardsProtocol<ClientboundPac
user.put(new ItemTagStorage());
user.put(new RecipeStorage(this));
user.put(new PlayerStorage());
user.put(new SignStorage());
}
@Override
@@ -26,12 +26,20 @@ import com.viaversion.viabackwards.api.rewriters.BackwardsStructuredItemRewriter
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21;
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.InventoryStateIdStorage;
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.RecipeStorage;
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.SignStorage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.HolderSet;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.SoundEvent;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataContainer;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.api.minecraft.item.Item;
@@ -45,8 +53,10 @@ import com.viaversion.viaversion.api.minecraft.item.data.Instrument1_21_2;
import com.viaversion.viaversion.api.minecraft.item.data.ItemModel;
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffect;
import com.viaversion.viaversion.api.minecraft.item.data.PotionEffectData;
import com.viaversion.viaversion.api.minecraft.item.data.Repairable;
import com.viaversion.viaversion.api.minecraft.item.data.UseCooldown;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
@@ -74,10 +84,7 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem
public void registerPackets() {
final BlockRewriter<ClientboundPacket1_21_2> blockRewriter = BlockRewriter.for1_20_2(protocol);
blockRewriter.registerBlockEvent(ClientboundPackets1_21_2.BLOCK_EVENT);
blockRewriter.registerBlockUpdate(ClientboundPackets1_21_2.BLOCK_UPDATE);
blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21_2.SECTION_BLOCKS_UPDATE);
blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21_2.LEVEL_EVENT, 2001);
blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21_2.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_20_2::new);
blockRewriter.registerBlockEntityData(ClientboundPackets1_21_2.BLOCK_ENTITY_DATA);
registerAdvancements1_20_3(ClientboundPackets1_21_2.UPDATE_ADVANCEMENTS);
@@ -85,6 +92,109 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem
registerMerchantOffers1_20_5(ClientboundPackets1_21_2.MERCHANT_OFFERS);
registerSetCreativeModeSlot(ServerboundPackets1_20_5.SET_CREATIVE_MODE_SLOT);
protocol.registerClientbound(ClientboundPackets1_21_2.LEVEL_CHUNK_WITH_LIGHT, wrapper -> {
final Chunk chunk = blockRewriter.handleChunk1_19(wrapper, ChunkType1_20_2::new);
blockRewriter.handleBlockEntities(null, chunk, wrapper.user());
if (!wrapper.user().getProtocolInfo().protocolVersion().equalTo(ProtocolVersion.v1_21)) {
return;
}
final EntityTracker tracker = wrapper.user().getEntityTracker(Protocol1_21_2To1_21.class);
final SignStorage storage = wrapper.user().get(SignStorage.class);
storage.removeSigns(chunk.getX(), chunk.getZ());
for (int i = 0; i < chunk.getSections().length; i++) {
final ChunkSection section = chunk.getSections()[i];
final DataPalette blockPalette = section.palette(PaletteType.BLOCKS);
boolean containsSign = false;
for (int idx = 0; idx < blockPalette.size(); idx++) {
if (signBlockState(blockPalette.idByIndex(idx))) {
containsSign = true;
break;
}
}
if (!containsSign) {
continue;
}
for (int idx = 0; idx < ChunkSection.SIZE; idx++) {
if (!signBlockState(blockPalette.idAt(idx))) {
continue;
}
storage.addSign(new BlockPosition(
ChunkSection.xFromIndex(idx) + (chunk.getX() << 4),
ChunkSection.yFromIndex(idx) + tracker.currentMinY() + (i << 4),
ChunkSection.zFromIndex(idx) + (chunk.getZ() << 4)
));
}
}
});
protocol.registerClientbound(ClientboundPackets1_21_2.BLOCK_UPDATE, wrapper -> {
final BlockPosition position = wrapper.passthrough(Types.BLOCK_POSITION1_14);
final int blockId = wrapper.read(Types.VAR_INT);
final int mappedBlockId = protocol.getMappingData().getNewBlockStateId(blockId);
wrapper.write(Types.VAR_INT, mappedBlockId);
if (!wrapper.user().getProtocolInfo().protocolVersion().equalTo(ProtocolVersion.v1_21)) {
return;
}
final SignStorage storage = wrapper.user().get(SignStorage.class);
storage.removeSign(position);
if (signBlockState(mappedBlockId)) {
storage.addSign(position);
}
});
protocol.registerClientbound(ClientboundPackets1_21_2.SECTION_BLOCKS_UPDATE, wrapper -> {
final long position = wrapper.passthrough(Types.LONG);
final int chunkX = (int) (position >> 42);
final int chunkY = (int) (position << 44 >> 44);
final int chunkZ = (int) (position << 22 >> 42);
final SignStorage signStorage = wrapper.user().get(SignStorage.class);
final boolean equalToV1_21 = wrapper.user().getProtocolInfo().protocolVersion().equalTo(ProtocolVersion.v1_21);
for (final BlockChangeRecord record : wrapper.passthrough(Types.VAR_LONG_BLOCK_CHANGE_ARRAY)) {
record.setBlockId(protocol.getMappingData().getNewBlockStateId(record.getBlockId()));
if (!equalToV1_21) {
continue;
}
final int x = record.getSectionX() + (chunkX << 4);
final int y = record.getSectionY() + (chunkY << 4);
final int z = record.getSectionZ() + (chunkZ << 4);
final BlockPosition pos = new BlockPosition(x, y, z);
if (signBlockState(record.getBlockId())) {
signStorage.addSign(pos);
} else {
signStorage.removeSign(pos);
}
}
});
protocol.registerClientbound(ClientboundPackets1_21_2.OPEN_SIGN_EDITOR, wrapper -> {
if (!wrapper.user().getProtocolInfo().protocolVersion().equalTo(ProtocolVersion.v1_21)) {
return;
}
final BlockPosition position = wrapper.passthrough(Types.BLOCK_POSITION1_14);
if (!wrapper.user().get(SignStorage.class).isSign(position)) {
wrapper.cancel();
}
});
protocol.registerClientbound(ClientboundPackets1_21_2.COOLDOWN, wrapper -> {
final MappingData mappingData = protocol.getMappingData();
final String itemIdentifier = wrapper.read(Types.STRING);
@@ -296,6 +406,10 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem
wrapper.write(Types.VAR_INT, (int) containerId);
}
private boolean signBlockState(final int blockStateId) {
return (blockStateId >= 4302 && blockStateId <= 4589) || (blockStateId >= 4762 && blockStateId <= 5625);
}
@Override
public Item handleItemToClient(final UserConnection connection, Item item) {
backupInconvertibleData(item);
@@ -348,9 +462,9 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem
backupTag.put("instrument_description", instrument.value().description());
}
final HolderSet repairable = data.get(StructuredDataKey.REPAIRABLE);
final Repairable repairable = data.get(StructuredDataKey.REPAIRABLE);
if (repairable != null) {
backupTag.put("repairable", holderSetToTag(repairable));
backupTag.put("repairable", holderSetToTag(repairable.items()));
}
final Enchantable enchantable = data.get(StructuredDataKey.ENCHANTABLE);
@@ -523,7 +637,7 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem
}
if (backupTag.contains("repairable")) {
data.set(StructuredDataKey.REPAIRABLE, restoreHolderSet(backupTag, "repairable"));
data.set(StructuredDataKey.REPAIRABLE, new Repairable(restoreHolderSet(backupTag, "repairable")));
}
final IntTag enchantable = backupTag.getIntTag("enchantable");
@@ -57,7 +57,7 @@ public final class ComponentRewriter1_21_2 extends JsonNBTComponentRewriter<Clie
}
removeDataComponents(componentsTag, BlockItemPacketRewriter1_21_2.NEW_DATA_TO_REMOVE);
removeDataComponents(componentsTag, StructuredDataKey.DAMAGE_RESISTANT, StructuredDataKey.LOCK); // No point in updating these
removeDataComponents(componentsTag, StructuredDataKey.DAMAGE_RESISTANT, StructuredDataKey.LOCK1_21_2); // No point in updating these
}
@Override
@@ -27,6 +27,8 @@ import com.viaversion.viabackwards.api.rewriters.BackwardsRegistryRewriter;
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.Protocol1_21_2To1_21;
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.PlayerStorage;
import com.viaversion.viabackwards.protocol.v1_21_2to1_21.storage.SignStorage;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
@@ -173,6 +175,11 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
wrapper.passthrough(Types.VAR_INT); // Portal cooldown
wrapper.read(Types.VAR_INT); // Sea level
final EntityTracker tracker = tracker(wrapper.user());
if (tracker.currentWorld() != null && !tracker.currentWorld().equals(world)) {
wrapper.user().put(new SignStorage());
}
trackWorldDataByKey1_20_5(wrapper.user(), dimensionId, world);
});
@@ -0,0 +1,45 @@
/*
* 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_2to1_21.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import java.util.HashSet;
import java.util.Set;
public final class SignStorage implements StorableObject {
private final Set<BlockPosition> signs = new HashSet<>();
public void addSign(final BlockPosition position) {
signs.add(position);
}
public boolean isSign(final BlockPosition position) {
return signs.contains(position);
}
public void removeSign(final BlockPosition position) {
signs.remove(position);
}
public void removeSigns(final int chunkX, final int chunkZ) {
signs.removeIf(pos -> pos.x() >> 4 == chunkX && pos.z() >> 4 == chunkZ);
}
}
@@ -89,6 +89,7 @@ public final class Protocol1_21_4To1_21_2 extends BackwardsProtocol<ClientboundP
translatableRewriter.registerBossEvent(ClientboundPackets1_21_2.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_21_2.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_21_2.SET_PLAYER_TEAM);
translatableRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21_2.PLAYER_COMBAT_KILL);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_2.SYSTEM_CHAT);
translatableRewriter.registerDisguisedChat(ClientboundPackets1_21_2.DISGUISED_CHAT);
@@ -23,6 +23,7 @@ import com.viaversion.viabackwards.api.rewriters.SoundRewriter;
import com.viaversion.viabackwards.protocol.v1_21_5to1_21_4.rewriter.BlockItemPacketRewriter1_21_5;
import com.viaversion.viabackwards.protocol.v1_21_5to1_21_4.rewriter.ComponentRewriter1_21_5;
import com.viaversion.viabackwards.protocol.v1_21_5to1_21_4.rewriter.EntityPacketRewriter1_21_5;
import com.viaversion.viabackwards.protocol.v1_21_5to1_21_4.rewriter.RegistryDataRewriter1_21_5;
import com.viaversion.viabackwards.protocol.v1_21_5to1_21_4.storage.HashedItemConverterStorage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Particle;
@@ -52,6 +53,7 @@ import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.packet.ServerboundPac
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPacket1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.util.Key;
@@ -75,6 +77,7 @@ public final class Protocol1_21_5To1_21_4 extends BackwardsProtocol<ClientboundP
};
private final ComponentRewriter1_21_5 translatableRewriter = new ComponentRewriter1_21_5(this);
private final TagRewriter<ClientboundPacket1_21_5> tagRewriter = new TagRewriter<>(this);
private final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter1_21_5(this);
public Protocol1_21_5To1_21_4() {
super(ClientboundPacket1_21_5.class, ClientboundPacket1_21_2.class, ServerboundPacket1_21_5.class, ServerboundPacket1_21_4.class);
@@ -84,6 +87,8 @@ public final class Protocol1_21_5To1_21_4 extends BackwardsProtocol<ClientboundP
protected void registerPackets() {
super.registerPackets();
registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, registryDataRewriter::handle);
tagRewriter.registerGeneric(ClientboundPackets1_21_5.UPDATE_TAGS);
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21.UPDATE_TAGS);
@@ -204,6 +209,11 @@ public final class Protocol1_21_5To1_21_4 extends BackwardsProtocol<ClientboundP
return itemRewriter;
}
@Override
public RegistryDataRewriter getRegistryDataRewriter() {
return registryDataRewriter;
}
@Override
public ParticleRewriter<ClientboundPacket1_21_5> getParticleRewriter() {
return particleRewriter;
@@ -67,7 +67,9 @@ import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_20_2;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_21_5;
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
import com.viaversion.viaversion.data.item.ItemHasherBase;
import com.viaversion.viaversion.libs.fastutil.ints.IntArrayList;
import com.viaversion.viaversion.libs.fastutil.ints.IntLinkedOpenHashSet;
import com.viaversion.viaversion.libs.fastutil.ints.IntList;
import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.packet.ServerboundPacket1_21_4;
import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.packet.ServerboundPackets1_21_4;
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.packet.ClientboundPacket1_21_5;
@@ -78,7 +80,6 @@ import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
import com.viaversion.viaversion.util.Either;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Limit;
import com.viaversion.viaversion.util.SerializerVersion;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -182,20 +183,37 @@ public final class BlockItemPacketRewriter1_21_5 extends BackwardsStructuredItem
protocol.registerClientbound(ClientboundPackets1_21_5.SET_EQUIPMENT, wrapper -> {
final int entityId = wrapper.passthrough(Types.VAR_INT);
final TrackedEntity trackedEntity = protocol.getEntityRewriter().tracker(wrapper.user()).entity(entityId);
// Remove saddle equipment, keep the rest
final IntList keptSlots = new IntArrayList();
final List<Item> keptItems = new ArrayList<>();
byte value;
do {
value = wrapper.passthrough(Types.BYTE);
value = wrapper.read(Types.BYTE);
final int equipmentSlot = value & 0x7F;
final Item item = wrapper.read(itemType());
if (equipmentSlot == SADDLE_EQUIPMENT_SLOT) {
// Send saddle entity data for horses
if (trackedEntity != null && trackedEntity.entityType().isOrHasParent(EntityTypes1_21_5.ABSTRACT_HORSE)) {
final Item item = wrapper.read(itemType());
sendSaddledEntityData(wrapper.user(), trackedEntity, entityId, item.identifier() == 800);
}
wrapper.cancel();
return;
} else {
keptSlots.add(equipmentSlot);
keptItems.add(handleItemToClient(wrapper.user(), item));
}
passthroughClientboundItem(wrapper);
} while (value < 0);
if (keptSlots.isEmpty()) {
wrapper.cancel();
return;
}
for (int i = 0; i < keptSlots.size(); i++) {
final int slot = keptSlots.getInt(i);
final boolean more = i < keptSlots.size() - 1;
wrapper.write(Types.BYTE, (byte) (more ? (slot | -128) : slot));
wrapper.write(mappedItemType(), keptItems.get(i));
}
});
protocol.registerClientbound(ClientboundPackets1_21_5.UPDATE_ADVANCEMENTS, wrapper -> {
@@ -172,12 +172,14 @@ public final class ComponentRewriter1_21_5 extends NBTComponentRewriter<Clientbo
handleAdventureModePredicate(componentsTag, "can_break", hiddenComponents);
handleEnchantments(componentsTag, "enchantments", hiddenComponents);
handleEnchantments(componentsTag, "stored_enchantments", hiddenComponents);
removeDataComponents(componentsTag, StructuredDataKey.INSTRUMENT1_21_5, StructuredDataKey.JUKEBOX_PLAYABLE1_21_5);
}
private void updateShowInTooltip(final CompoundTag tag, final String key, final Set<String> hiddenComponents) {
final CompoundTag data = getNamespacedCompoundTag(tag, key);
if (data != null) {
data.putBoolean("show_in_tooltip", hiddenComponents.contains(key));
data.putBoolean("show_in_tooltip", !hiddenComponents.contains(key));
}
}
@@ -190,7 +192,7 @@ public final class ComponentRewriter1_21_5 extends NBTComponentRewriter<Clientbo
removeDataComponents(componentsTag, key);
final CompoundTag predicate = new CompoundTag();
predicate.put("predicates", blockPredicates);
predicate.putBoolean("show_in_tooltip", hiddenComponents.contains(key));
predicate.putBoolean("show_in_tooltip", !hiddenComponents.contains(key));
componentsTag.put(key, predicate);
}
@@ -200,7 +202,7 @@ public final class ComponentRewriter1_21_5 extends NBTComponentRewriter<Clientbo
removeNamespaced(componentsTag, key);
final CompoundTag enchantments = new CompoundTag();
enchantments.put("levels", levels);
enchantments.putBoolean("show_in_tooltip", hiddenComponents.contains(key));
enchantments.putBoolean("show_in_tooltip", !hiddenComponents.contains(key));
componentsTag.put(key, enchantments);
}
}
@@ -17,18 +17,11 @@
*/
package com.viaversion.viabackwards.protocol.v1_21_5to1_21_4.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.viabackwards.api.rewriters.BackwardsRegistryRewriter;
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
import com.viaversion.viabackwards.protocol.v1_21_5to1_21_4.Protocol1_21_5To1_21_4;
import com.viaversion.viabackwards.protocol.v1_21_5to1_21_4.storage.HashedItemConverterStorage;
import com.viaversion.viabackwards.protocol.v1_21_5to1_21_4.storage.HorseDataStorage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.entity.TrackedEntity;
import com.viaversion.viaversion.api.minecraft.Holder;
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
import com.viaversion.viaversion.api.minecraft.WolfVariant;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_5;
@@ -38,22 +31,13 @@ import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1
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.protocols.v1_20_5to1_21.packet.ClientboundConfigurationPackets1_21;
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.packet.ClientboundPacket1_21_5;
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.packet.ClientboundPackets1_21_5;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ClientboundPackets1_21_2;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
import com.viaversion.viaversion.util.Key;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public final class EntityPacketRewriter1_21_5 extends EntityRewriter<ClientboundPacket1_21_5, Protocol1_21_5To1_21_4> {
private static final Set<String> NEW_REGISTRIES = Set.of("pig_variant", "cow_variant", "frog_variant", "cat_variant",
"chicken_variant", "test_environment", "test_instance", "wolf_sound_variant");
public EntityPacketRewriter1_21_5(final Protocol1_21_5To1_21_4 protocol) {
super(protocol, protocol.mappedTypes().entityDataTypes().optionalComponentType, protocol.mappedTypes().entityDataTypes().booleanType);
}
@@ -112,69 +96,6 @@ public final class EntityPacketRewriter1_21_5 extends EntityRewriter<Clientbound
}
});
final RegistryDataRewriter registryDataRewriter = new BackwardsRegistryRewriter(protocol) {
@Override
public RegistryEntry[] handle(final UserConnection connection, final String key, final RegistryEntry[] entries) {
final boolean trimPatternRegistry = key.equals("trim_pattern");
if (trimPatternRegistry || key.equals("trim_material")) {
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);
}
for (final RegistryEntry entry : entries) {
if (entry.tag() == null) {
continue;
}
final CompoundTag variant = (CompoundTag) entry.tag();
final CompoundTag assets = (CompoundTag) variant.remove("assets");
variant.put("wild_texture", assets.get("wild"));
variant.put("tame_texture", assets.get("tame"));
variant.put("angry_texture", assets.get("angry"));
variant.put("biomes", new ListTag<>(StringTag.class));
}
return entries;
}
private void updateTrim(final RegistryEntry[] entries, final String itemKey) {
for (final RegistryEntry entry : entries) {
if (entry.tag() == null) {
continue;
}
final CompoundTag tag = (CompoundTag) entry.tag();
tag.putString(itemKey, "stone"); // dummy ingredient
}
}
};
protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, wrapper -> {
final String registryKey = Key.stripMinecraftNamespace(wrapper.passthrough(Types.STRING));
if (NEW_REGISTRIES.contains(registryKey)) {
wrapper.cancel();
return;
}
final RegistryEntry[] entries = wrapper.read(Types.REGISTRY_ENTRY_ARRAY);
if (registryKey.equals("enchantment")) {
final List<String> identifiers = new ArrayList<>(entries.length);
for (final RegistryEntry entry : entries) {
identifiers.add(entry.key());
}
wrapper.user().get(HashedItemConverterStorage.class).setEnchantments(identifiers);
}
wrapper.write(Types.REGISTRY_ENTRY_ARRAY, registryDataRewriter.handle(wrapper.user(), registryKey, entries));
});
protocol.registerClientbound(ClientboundPackets1_21_5.LOGIN, wrapper -> {
final int entityId = wrapper.passthrough(Types.INT); // Entity id
wrapper.passthrough(Types.BOOLEAN); // Hardcore
@@ -201,7 +122,7 @@ public final class EntityPacketRewriter1_21_5 extends EntityRewriter<Clientbound
wrapper.passthrough(Types.STRING); // Team Name
final byte action = wrapper.passthrough(Types.BYTE); // Mode
if (action == 0 || action == 2) {
wrapper.passthrough(Types.TAG); // Display Name
protocol.getComponentRewriter().passthroughAndProcess(wrapper); // Display name
wrapper.passthrough(Types.BYTE); // Flags
final int nametagVisibility = wrapper.read(Types.VAR_INT);
@@ -210,26 +131,12 @@ public final class EntityPacketRewriter1_21_5 extends EntityRewriter<Clientbound
wrapper.write(Types.STRING, collision(collisionRule));
wrapper.passthrough(Types.VAR_INT); // Color
wrapper.passthrough(Types.TAG); // Prefix
wrapper.passthrough(Types.TAG); // Suffix
protocol.getComponentRewriter().passthroughAndProcess(wrapper); // Prefix
protocol.getComponentRewriter().passthroughAndProcess(wrapper); // Suffix
}
});
}
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";
@@ -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_5to1_21_4.rewriter;
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.api.rewriters.BackwardsRegistryRewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
import java.util.List;
public final class RegistryDataRewriter1_21_5 extends BackwardsRegistryRewriter {
public RegistryDataRewriter1_21_5(final BackwardsProtocol<?, ?, ?, ?> protocol) {
super(protocol);
final List<String> newRegistries = List.of("pig_variant", "cow_variant", "frog_variant", "cat_variant",
"chicken_variant", "test_environment", "test_instance", "wolf_sound_variant");
for (final String registry : newRegistries) {
remove(registry);
}
}
@Override
public RegistryEntry[] handle(final UserConnection connection, final String key, final RegistryEntry[] entries) {
final boolean trimPatternRegistry = key.equals("trim_pattern");
if (trimPatternRegistry || key.equals("trim_material")) {
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);
}
for (final RegistryEntry entry : entries) {
if (entry.tag() == null) {
continue;
}
final CompoundTag variant = (CompoundTag) entry.tag();
final CompoundTag assets = (CompoundTag) variant.remove("assets");
variant.put("wild_texture", assets.get("wild"));
variant.put("tame_texture", assets.get("tame"));
variant.put("angry_texture", assets.get("angry"));
variant.put("biomes", new ListTag<>(StringTag.class));
}
return entries;
}
private void updateTrim(final RegistryEntry[] entries, final String itemKey) {
for (final RegistryEntry entry : entries) {
if (entry.tag() == null) {
continue;
}
final CompoundTag tag = (CompoundTag) entry.tag();
tag.putString(itemKey, "stone"); // dummy ingredient
}
}
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
}
}
}
}
@@ -25,25 +25,17 @@ import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.codec.CodecRegistryContext;
import com.viaversion.viaversion.codec.hash.HashFunction;
import com.viaversion.viaversion.codec.hash.HashOps;
import java.util.ArrayList;
import java.util.List;
public class HashedItemConverterStorage implements StorableObject {
private final List<String> enchantments = new ArrayList<>();
private final Hasher hasher;
public HashedItemConverterStorage(final Protocol<?, ?, ?, ?> protocol) {
final RegistryAccess registryAccess = RegistryAccess.of(this.enchantments, protocol.getMappingData());
final RegistryAccess registryAccess = RegistryAccess.of(protocol);
final CodecContext context = new CodecRegistryContext(protocol, registryAccess, false);
this.hasher = new HashOps(context, HashFunction.CRC32C);
}
public void setEnchantments(final List<String> enchantments) {
this.enchantments.clear();
this.enchantments.addAll(enchantments);
}
public Hasher hasher() {
return hasher; // reusable
}
@@ -19,6 +19,7 @@ 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.ViaBackwards;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
import com.viaversion.viabackwards.api.rewriters.SoundRewriter;
@@ -29,6 +30,7 @@ import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.provider.DialogViewP
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.rewriter.RegistryDataRewriter1_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;
@@ -61,6 +63,7 @@ import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPac
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPackets1_21_6;
import com.viaversion.viaversion.rewriter.AttributeRewriter;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.util.Key;
@@ -75,6 +78,7 @@ public final class Protocol1_21_6To1_21_5 extends BackwardsProtocol<ClientboundP
private final ParticleRewriter<ClientboundPacket1_21_6> particleRewriter = new ParticleRewriter<>(this);
private final NBTComponentRewriter<ClientboundPacket1_21_6> translatableRewriter = new ComponentRewriter1_21_6(this);
private final TagRewriter<ClientboundPacket1_21_6> tagRewriter = new TagRewriter<>(this);
private final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter1_21_6(this);
public Protocol1_21_6To1_21_5() {
super(ClientboundPacket1_21_6.class, ClientboundPacket1_21_5.class, ServerboundPacket1_21_6.class, ServerboundPacket1_21_5.class);
@@ -84,6 +88,8 @@ public final class Protocol1_21_6To1_21_5 extends BackwardsProtocol<ClientboundP
protected void registerPackets() {
super.registerPackets();
registerClientbound(ClientboundConfigurationPackets1_21_6.REGISTRY_DATA, registryDataRewriter::handle);
registerClientbound(ClientboundPackets1_21_6.UPDATE_TAGS, this::updateTags);
registerClientbound(ClientboundConfigurationPackets1_21_6.UPDATE_TAGS, this::updateTags);
@@ -126,6 +132,7 @@ public final class Protocol1_21_6To1_21_5 extends BackwardsProtocol<ClientboundP
translatableRewriter.registerBossEvent(ClientboundPackets1_21_6.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_6.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_21_6.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_21_5(ClientboundPackets1_21_6.SET_PLAYER_TEAM);
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);
@@ -144,10 +151,15 @@ public final class Protocol1_21_6To1_21_5 extends BackwardsProtocol<ClientboundP
final short difficulty = wrapper.read(Types.UNSIGNED_BYTE);
wrapper.write(Types.VAR_INT, (int) difficulty);
});
registerServerbound(ServerboundPackets1_21_5.CHAT_COMMAND, this::handleClickEvents);
registerServerbound(ServerboundPackets1_21_5.CHAT_COMMAND_SIGNED, this::handleClickEvents);
// 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();
if (!ViaBackwards.getConfig().dialogsViaChests()) {
return;
}
final RegistryAndTags registryAndTags = wrapper.user().get(RegistryAndTags.class);
final ServerLinks serverLinks = wrapper.user().get(ServerLinks.class);
@@ -164,6 +176,9 @@ public final class Protocol1_21_6To1_21_5 extends BackwardsProtocol<ClientboundP
});
registerClientbound(ClientboundConfigurationPackets1_21_6.SHOW_DIALOG, null, wrapper -> {
wrapper.cancel();
if (!ViaBackwards.getConfig().dialogsViaChests()) {
return;
}
final RegistryAndTags registryAndTags = wrapper.user().get(RegistryAndTags.class);
final ServerLinks serverLinks = wrapper.user().get(ServerLinks.class);
@@ -178,9 +193,6 @@ public final class Protocol1_21_6To1_21_5 extends BackwardsProtocol<ClientboundP
registerClientbound(ClientboundPackets1_21_6.SERVER_LINKS, this::storeServerLinks);
registerClientbound(ClientboundConfigurationPackets1_21_6.SERVER_LINKS, this::storeServerLinks);
registerServerbound(ServerboundPackets1_21_5.CHAT_COMMAND, this::handleClickEvents);
registerServerbound(ServerboundPackets1_21_5.CHAT_COMMAND_SIGNED, this::handleClickEvents);
// 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);
@@ -285,6 +297,10 @@ public final class Protocol1_21_6To1_21_5 extends BackwardsProtocol<ClientboundP
private void clearDialog(final PacketWrapper wrapper) {
wrapper.cancel();
if (!ViaBackwards.getConfig().dialogsViaChests()) {
return;
}
final DialogViewProvider provider = Via.getManager().getProviders().get(DialogViewProvider.class);
provider.closeDialog(wrapper.user());
}
@@ -343,6 +359,11 @@ public final class Protocol1_21_6To1_21_5 extends BackwardsProtocol<ClientboundP
return itemRewriter;
}
@Override
public RegistryDataRewriter getRegistryDataRewriter() {
return registryDataRewriter;
}
@Override
public ParticleRewriter<ClientboundPacket1_21_6> getParticleRewriter() {
return particleRewriter;
@@ -74,7 +74,7 @@ public class Button implements Widget {
for (final String event : CLICK_EVENTS) {
if (Key.stripMinecraftNamespace(type).equals(event)) {
clickEvent = actionTag;
clickEvent = actionTag.copy();
clickEvent.put("action", clickEvent.remove("type"));
return;
}
@@ -132,7 +132,7 @@ public final class Dialog implements Widget {
private void fillNoticeDialog(final CompoundTag tag) {
final CompoundTag actionTag = tag.getCompoundTag("action");
actionButton = actionTag == null ? Button.DEFAULT : actionButton;
actionButton = actionTag == null ? Button.DEFAULT : new Button(this, actionTag);
}
private void fillServerLinksDialog(final ServerLinks serverLinks, final CompoundTag tag) {
@@ -150,7 +150,7 @@ public final class Dialog implements Widget {
}
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.
// Hold them as either a list of inlined / singleton inlined, a list of registry entries / singleton entry or a tag.
ListTag<CompoundTag> dialogsTag = tag.getListTag("dialogs", CompoundTag.class);
if (dialogsTag == null) {
CompoundTag dialogTag = tag.getCompoundTag("dialogs");
@@ -159,16 +159,23 @@ public final class Dialog implements Widget {
dialogsTag.add(dialogTag);
}
ListTag<StringTag> registryDialogsTag = tag.getListTag("dialogs", StringTag.class);
StringTag registryDialogTag = tag.getStringTag("dialogs");
if (registryDialogTag != null) {
registryDialogsTag = new ListTag<>(StringTag.class);
registryDialogsTag.add(registryDialogTag);
}
if (registryDialogsTag != 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);
for (final StringTag nameTag : registryDialogsTag) {
final String key = nameTag.getValue();
if (key.startsWith("#")) {
for (final CompoundTag entry : registryAndTags.fromRegistryKey(key.substring(1))) {
dialogsTag.add(entry);
}
} else {
dialogsTag.add(registryAndTags.fromRegistry(key));
}
} else {
dialogsTag.add(registryAndTags.fromRegistry(key));
}
}
}
@@ -85,11 +85,18 @@ public class ChestDialogViewProvider implements DialogViewProvider {
texts.add(textWidget.label());
dialog.widgets().remove(textWidget);
} else if (!texts.isEmpty()) {
// Flush collected texts before adding the non-text widget
dialog.widgets().add(dialog.widgets().indexOf(widget), new MultiTextWidget(texts.toArray(Tag[]::new)));
texts.clear();
}
}
// Flush remaining texts if any
if (!texts.isEmpty()) {
dialog.widgets().add(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) {
@@ -210,8 +217,9 @@ public class ChestDialogViewProvider implements DialogViewProvider {
}
}
// Resync inventory view if the actions above didn't close the dialog.
if (connection.has(ChestDialogStorage.class) && storage.phase() == ChestDialogStorage.Phase.DIALOG_VIEW) {
// Resync inventory view if the actions above didn't close the dialog nor opened another one.
final ChestDialogStorage currentStorage = connection.get(ChestDialogStorage.class);
if (currentStorage == storage && connection.has(ChestDialogStorage.class) && storage.phase() == ChestDialogStorage.Phase.DIALOG_VIEW) {
updateDialog(connection, storage.dialog());
}
return true;
@@ -274,17 +282,19 @@ public class ChestDialogViewProvider implements DialogViewProvider {
}
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 List<Tag> lines = new ArrayList<>();
for (final Tag label : multiTextWidget.labels()) {
final Tag[] split = ChatUtil.split(fixStyle(label), "\n");
for (final Tag line : split) {
lines.add(handleTag(connection, line));
}
}
final Tag[] lore = new Tag[length - 1];
for (int i = 1; i < length; i++) {
lore[i - 1] = handleTag(connection, fixStyle(multiTextWidget.labels()[i]));
final Tag[] lore = new Tag[lines.size() - 1];
for (int i = 1; i < lines.size(); i++) {
lore[i - 1] = lines.get(i);
}
return createItem("minecraft:paper", name, lore);
return createItem("minecraft:paper", lines.get(0), lore);
}
protected Item getBooleanInput(final UserConnection connection, final BooleanInput booleanInput) {
@@ -17,29 +17,18 @@
*/
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> {
@@ -86,31 +75,6 @@ public final class EntityPacketRewriter1_21_6 extends EntityRewriter<Clientbound
}
});
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 -> {
wrapper.passthrough(Types.VAR_INT); // Entity ID
@@ -0,0 +1,59 @@
/*
* 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.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.rewriters.BackwardsRegistryRewriter;
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.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 RegistryDataRewriter1_21_6 extends BackwardsRegistryRewriter {
public RegistryDataRewriter1_21_6(final BackwardsProtocol<?, ?, ?, ?> protocol) {
super(protocol);
remove("dialog"); // Tracked and now removed
}
@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);
}
}
@@ -19,6 +19,7 @@ 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.ViaBackwards;
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;
@@ -59,6 +60,10 @@ public final class ClickEvents implements StorableObject {
public static void handleClickEvent(final UserConnection connection, final CompoundTag clickEvent) {
final String action = Key.stripMinecraftNamespace(clickEvent.getString("action"));
if ("show_dialog".equals(action)) {
if (!ViaBackwards.getConfig().dialogsViaChests()) {
return;
}
final RegistryAndTags registryAndTags = connection.get(RegistryAndTags.class);
final ServerLinks serverLinks = connection.get(ServerLinks.class);
@@ -19,6 +19,7 @@ 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.BackwardsRegistryRewriter;
import com.viaversion.viabackwards.api.rewriters.SoundRewriter;
import com.viaversion.viabackwards.api.rewriters.text.NBTComponentRewriter;
import com.viaversion.viabackwards.api.rewriters.text.TranslatableRewriter;
@@ -42,6 +43,7 @@ import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPac
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.RegistryDataRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -55,6 +57,7 @@ public final class Protocol1_21_7To1_21_6 extends BackwardsProtocol<ClientboundP
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);
private final RegistryDataRewriter registryDataRewriter = new BackwardsRegistryRewriter(this);
public Protocol1_21_7To1_21_6() {
super(ClientboundPacket1_21_6.class, ClientboundPacket1_21_6.class, ServerboundPacket1_21_6.class, ServerboundPacket1_21_6.class);
@@ -64,6 +67,8 @@ public final class Protocol1_21_7To1_21_6 extends BackwardsProtocol<ClientboundP
protected void registerPackets() {
super.registerPackets();
registerClientbound(ClientboundConfigurationPackets1_21_6.REGISTRY_DATA, registryDataRewriter::handle);
tagRewriter.registerGeneric(ClientboundPackets1_21_6.UPDATE_TAGS);
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21_6.UPDATE_TAGS);
@@ -80,6 +85,7 @@ public final class Protocol1_21_7To1_21_6 extends BackwardsProtocol<ClientboundP
translatableRewriter.registerBossEvent(ClientboundPackets1_21_6.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_6.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_21_6.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_21_5(ClientboundPackets1_21_6.SET_PLAYER_TEAM);
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);
@@ -127,6 +133,11 @@ public final class Protocol1_21_7To1_21_6 extends BackwardsProtocol<ClientboundP
return itemRewriter;
}
@Override
public RegistryDataRewriter getRegistryDataRewriter() {
return registryDataRewriter;
}
@Override
public ParticleRewriter<ClientboundPacket1_21_6> getParticleRewriter() {
return particleRewriter;
@@ -17,7 +17,6 @@
*/
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;
@@ -25,10 +24,8 @@ 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> {
@@ -45,9 +42,6 @@ public final class EntityPacketRewriter1_21_7 extends EntityRewriter<Clientbound
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
@@ -26,6 +26,8 @@ import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.rewriter.BlockItemPa
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.rewriter.ComponentRewriter1_21_9;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.rewriter.EntityPacketRewriter1_21_9;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.rewriter.ParticleRewriter1_21_9;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.rewriter.RegistryDataRewriter1_21_9;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.storage.DimensionScaleStorage;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.storage.PlayerRotationStorage;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.tracker.EntityTracker1_21_9;
import com.viaversion.viaversion.api.connection.UserConnection;
@@ -54,6 +56,7 @@ import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundPac
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ServerboundConfigurationPackets1_21_9;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ServerboundPacket1_21_9;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
@@ -67,6 +70,7 @@ public final class Protocol1_21_9To1_21_7 extends BackwardsProtocol<ClientboundP
private final ParticleRewriter<ClientboundPacket1_21_9> particleRewriter = new ParticleRewriter1_21_9(this);
private final NBTComponentRewriter<ClientboundPacket1_21_9> translatableRewriter = new ComponentRewriter1_21_9(this);
private final TagRewriter<ClientboundPacket1_21_9> tagRewriter = new TagRewriter<>(this);
private final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter1_21_9(this);
public Protocol1_21_9To1_21_7() {
super(ClientboundPacket1_21_9.class, ClientboundPacket1_21_6.class, ServerboundPacket1_21_9.class, ServerboundPacket1_21_6.class);
@@ -76,6 +80,8 @@ public final class Protocol1_21_9To1_21_7 extends BackwardsProtocol<ClientboundP
protected void registerPackets() {
super.registerPackets();
registerClientbound(ClientboundConfigurationPackets1_21_9.REGISTRY_DATA, registryDataRewriter::handle);
tagRewriter.registerGeneric(ClientboundPackets1_21_9.UPDATE_TAGS);
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21_9.UPDATE_TAGS);
@@ -93,6 +99,7 @@ public final class Protocol1_21_9To1_21_7 extends BackwardsProtocol<ClientboundP
translatableRewriter.registerBossEvent(ClientboundPackets1_21_9.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_9.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_21_9.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_21_5(ClientboundPackets1_21_9.SET_PLAYER_TEAM);
translatableRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21_9.PLAYER_COMBAT_KILL);
translatableRewriter.registerPlayerInfoUpdate1_21_4(ClientboundPackets1_21_9.PLAYER_INFO_UPDATE);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_9.SYSTEM_CHAT);
@@ -185,12 +192,19 @@ public final class Protocol1_21_9To1_21_7 extends BackwardsProtocol<ClientboundP
}
});
registerServerbound(ServerboundPackets1_21_6.DEBUG_SAMPLE_SUBSCRIPTION, wrapper -> {
final int sampleType = wrapper.read(Types.VAR_INT);
if (sampleType == 0) { // TICK_TIME
wrapper.write(Types.VAR_INT, 1); // Subscription count
wrapper.write(Types.VAR_INT, 0); // Subscription registry id (DEDICATED_SERVER_TICK_TIME)
}
});
cancelClientbound(ClientboundPackets1_21_9.DEBUG_BLOCK_VALUE);
cancelClientbound(ClientboundPackets1_21_9.DEBUG_CHUNK_VALUE);
cancelClientbound(ClientboundPackets1_21_9.DEBUG_ENTITY_VALUE);
cancelClientbound(ClientboundPackets1_21_9.DEBUG_EVENT);
cancelClientbound(ClientboundPackets1_21_9.GAME_EVENT_TEST_HIGHLIGHT_POS);
cancelServerbound(ServerboundPackets1_21_6.DEBUG_SAMPLE_SUBSCRIPTION);
}
@Override
@@ -198,6 +212,7 @@ public final class Protocol1_21_9To1_21_7 extends BackwardsProtocol<ClientboundP
addEntityTracker(connection, new EntityTracker1_21_9(connection, EntityTypes1_21_9.PLAYER));
addItemHasher(connection, new ItemHasherBase(this, connection));
connection.put(new PlayerRotationStorage());
connection.put(new DimensionScaleStorage());
}
@Override
@@ -215,6 +230,11 @@ public final class Protocol1_21_9To1_21_7 extends BackwardsProtocol<ClientboundP
return itemRewriter;
}
@Override
public RegistryDataRewriter getRegistryDataRewriter() {
return registryDataRewriter;
}
@Override
public ParticleRewriter<ClientboundPacket1_21_9> getParticleRewriter() {
return particleRewriter;
@@ -18,13 +18,20 @@
package com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.viabackwards.api.rewriters.BackwardsStructuredItemRewriter;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.Protocol1_21_9To1_21_7;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.storage.DimensionScaleStorage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.ResolvableProfile;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
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.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Types;
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.ServerboundPacket1_21_6;
@@ -38,6 +45,8 @@ import static com.viaversion.viaversion.protocols.v1_21_7to1_21_9.rewriter.Block
import static com.viaversion.viaversion.protocols.v1_21_7to1_21_9.rewriter.BlockItemPacketRewriter1_21_9.upgradeData;
public final class BlockItemPacketRewriter1_21_9 extends BackwardsStructuredItemRewriter<ClientboundPacket1_21_9, ServerboundPacket1_21_6, Protocol1_21_9To1_21_7> {
private static final int SIGN_BOCK_ENTITY_ID = 7;
private static final int HANGING_SIGN_BOCK_ENTITY_ID = 8;
public BlockItemPacketRewriter1_21_9(final Protocol1_21_9To1_21_7 protocol) {
super(protocol);
@@ -50,8 +59,8 @@ public final class BlockItemPacketRewriter1_21_9 extends BackwardsStructuredItem
blockRewriter.registerBlockUpdate(ClientboundPackets1_21_9.BLOCK_UPDATE);
blockRewriter.registerSectionBlocksUpdate1_20(ClientboundPackets1_21_9.SECTION_BLOCKS_UPDATE);
blockRewriter.registerLevelEvent1_21(ClientboundPackets1_21_9.LEVEL_EVENT, 2001);
blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21_9.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_21_5::new);
blockRewriter.registerBlockEntityData(ClientboundPackets1_21_9.BLOCK_ENTITY_DATA);
blockRewriter.registerLevelChunk1_19(ClientboundPackets1_21_9.LEVEL_CHUNK_WITH_LIGHT, ChunkType1_21_5::new, this::handleBlockEntity);
blockRewriter.registerBlockEntityData(ClientboundPackets1_21_9.BLOCK_ENTITY_DATA, this::handleBlockEntity);
registerSetCursorItem(ClientboundPackets1_21_9.SET_CURSOR_ITEM);
registerSetPlayerInventory(ClientboundPackets1_21_9.SET_PLAYER_INVENTORY);
@@ -68,6 +77,9 @@ public final class BlockItemPacketRewriter1_21_9 extends BackwardsStructuredItem
recipeRewriter.registerUpdateRecipes(ClientboundPackets1_21_9.UPDATE_RECIPES);
recipeRewriter.registerRecipeBookAdd(ClientboundPackets1_21_9.RECIPE_BOOK_ADD);
recipeRewriter.registerPlaceGhostRecipe(ClientboundPackets1_21_9.PLACE_GHOST_RECIPE);
protocol.registerClientbound(ClientboundPackets1_21_9.INITIALIZE_BORDER, this::updateBorderCenter);
protocol.registerClientbound(ClientboundPackets1_21_9.SET_BORDER_CENTER, this::updateBorderCenter);
}
@Override
@@ -123,4 +135,44 @@ public final class BlockItemPacketRewriter1_21_9 extends BackwardsStructuredItem
));
}
}
private void handleBlockEntity(final UserConnection connection, final BlockEntity blockEntity) {
final CompoundTag tag = blockEntity.tag();
if (tag == null) {
return;
}
if (blockEntity.typeId() == SIGN_BOCK_ENTITY_ID || blockEntity.typeId() == HANGING_SIGN_BOCK_ENTITY_ID) {
updateSignMessages(connection, tag.getCompoundTag("front_text"));
updateSignMessages(connection, tag.getCompoundTag("back_text"));
}
}
private void updateSignMessages(final UserConnection connection, final CompoundTag tag) {
if (tag == null) {
return;
}
final ListTag<?> messages = tag.getListTag("messages");
protocol.getComponentRewriter().processTag(connection, messages);
final ListTag<?> filteredMessages = tag.getListTag("filtered_messages");
if (filteredMessages != null) {
protocol.getComponentRewriter().processTag(connection, filteredMessages);
}
}
private void updateBorderCenter(final PacketWrapper wrapper) {
double centerX = wrapper.read(Types.DOUBLE);
double centerZ = wrapper.read(Types.DOUBLE);
final EntityTracker tracker = protocol.getEntityRewriter().tracker(wrapper.user());
if (tracker.currentDimensionId() != -1) {
final double scale = wrapper.user().get(DimensionScaleStorage.class).getScale(tracker.currentDimensionId());
centerX *= scale;
centerZ *= scale;
}
wrapper.write(Types.DOUBLE, centerX);
wrapper.write(Types.DOUBLE, centerZ);
}
}
@@ -30,6 +30,25 @@ public final class ComponentRewriter1_21_9 extends NBTComponentRewriter<Clientbo
super(protocol);
}
@Override
protected void processCompoundTag(final UserConnection connection, final CompoundTag tag) {
super.processCompoundTag(connection, tag);
// Throw out the new object type and its properties
final String type = tag.getString("type");
if ("object".equals(type)) {
tag.putString("text", "");
tag.remove("type");
}
if (tag.remove("sprite") != null) {
tag.putString("text", "");
}
if (tag.remove("player") != null) {
tag.putString("text", "");
}
tag.remove("atlas");
}
@Override
protected void handleShowItem(final UserConnection connection, final CompoundTag itemTag, final CompoundTag componentsTag) {
super.handleShowItem(connection, itemTag, componentsTag);
@@ -20,7 +20,6 @@ package com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viabackwards.api.rewriters.BackwardsRegistryRewriter;
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.Protocol1_21_9To1_21_7;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.storage.MannequinData;
@@ -40,10 +39,8 @@ import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
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.ServerboundPackets1_21_6;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundConfigurationPackets1_21_9;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundPacket1_21_9;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundPackets1_21_9;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
import com.viaversion.viaversion.rewriter.entitydata.EntityDataHandler;
import com.viaversion.viaversion.util.ChatColorUtil;
import java.util.BitSet;
@@ -127,9 +124,6 @@ public final class EntityPacketRewriter1_21_9 extends EntityRewriter<Clientbound
wrapper.read(Types.FLOAT); // Pitch
});
final RegistryDataRewriter registryDataRewriter = new BackwardsRegistryRewriter(protocol);
protocol.registerClientbound(ClientboundConfigurationPackets1_21_9.REGISTRY_DATA, registryDataRewriter::handle);
protocol.registerServerbound(ServerboundPackets1_21_6.MOVE_PLAYER_POS_ROT, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
@@ -0,0 +1,52 @@
/*
* 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_9to1_21_7.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.rewriters.BackwardsRegistryRewriter;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.storage.DimensionScaleStorage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
public final class RegistryDataRewriter1_21_9 extends BackwardsRegistryRewriter {
public RegistryDataRewriter1_21_9(final BackwardsProtocol<?, ?, ?, ?> protocol) {
super(protocol);
}
@Override
public void trackDimensionAndBiomes(final UserConnection connection, final String registryKey, final RegistryEntry[] entries) {
super.trackDimensionAndBiomes(connection, registryKey, entries);
if (!registryKey.equals("dimension_type")) {
return;
}
final DimensionScaleStorage dimensionScaleStorage = connection.get(DimensionScaleStorage.class);
for (int i = 0; i < entries.length; i++) {
final RegistryEntry entry = entries[i];
final CompoundTag dimension = (CompoundTag) entry.tag();
if (dimension == null) {
continue;
}
final double coordinateScale = dimension.getDouble("coordinate_scale", 1);
dimensionScaleStorage.setScale(i, coordinateScale);
}
}
}
@@ -0,0 +1,35 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* 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_9to1_21_7.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
import java.util.HashMap;
import java.util.Map;
public final class DimensionScaleStorage implements StorableObject {
private final Map<Integer, Double> dimensionScales = new HashMap<>(4);
public double getScale(final int dimensionId) {
return dimensionScales.getOrDefault(dimensionId, 1D);
}
public void setScale(final int dimensionId, final double scale) {
dimensionScales.put(dimensionId, scale);
}
}
@@ -93,6 +93,7 @@ public final class Protocol1_21To1_20_5 extends BackwardsProtocol<ClientboundPac
translatableRewriter.registerBossEvent(ClientboundPackets1_21.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_21.TAB_LIST);
translatableRewriter.registerSetPlayerTeam1_13(ClientboundPackets1_21.SET_PLAYER_TEAM);
translatableRewriter.registerPlayerCombatKill1_20(ClientboundPackets1_21.PLAYER_COMBAT_KILL);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21.SYSTEM_CHAT);
translatableRewriter.registerPing();
@@ -324,7 +324,7 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe
if (songIdentifier != null) {
song = EitherHolder.of(songIdentifier);
} else {
song = EitherHolder.of(restoreHolder(tag, "song", songTag -> {
song = EitherHolder.of(restoreHolder(jukeboxPlayableTag, "song", songTag -> {
final Holder<SoundEvent> soundEvent = restoreSoundEventHolder(songTag);
final Tag description = songTag.get("description");
final float lengthInSeconds = songTag.getFloat("length_in_seconds");
@@ -45,6 +45,9 @@ map-display-entities: true
# Suppresses warnings of missing emulations for certain features that are not supported (e.g. world height in 1.17+).
suppress-emulation-warnings: false
#
# If enabled, dialogs will be shown via chest inventories for 1.21.5 clients on 1.21.6+ servers.
dialogs-via-chests: true
#
# Dialog styling. You can also use translation keys here.
dialog-style:
page-navigation-title: "&9&lPage navigation"
File diff suppressed because it is too large. Load diff
@@ -1,4 +1,172 @@
{
"1.21.11": {
"advancements.adventure.spear_many_mobs.description": "Hit five mobs in the same Charge attack using the Spear",
"advancements.adventure.spear_many_mobs.title": "Mob Kabob",
"advMode.setCommand.disabled": "Command set: %s, but command blocks are still disabled",
"chat.queue.tooltip": "Click to display next message",
"commands.stopwatch.already_exists": "Stopwatch '%s' already exists",
"commands.stopwatch.create.success": "Created Stopwatch '%s'",
"commands.stopwatch.does_not_exist": "Stopwatch '%s' does not exist",
"commands.stopwatch.query": "Stopwatch '%s' has run for %ss",
"commands.stopwatch.remove.success": "Removed Stopwatch '%s'",
"commands.stopwatch.restart.success": "Restarted Stopwatch '%s'",
"death.attack.spear": "%1$s was speared by %2$s",
"death.attack.spear.item": "%1$s was speared by %2$s using %3$s",
"debug.crash.message.rebindable": "%s + %s is held down. This will crash the game unless released.",
"debug.entry.currently.inOverlay": "%s: Currently only in debug overlay",
"debug.entry.overlay": "In Overlay",
"debug.profiling.start.rebindable": "Profiling started for %s seconds. Use %s + %s to stop early",
"effect.minecraft.breath_of_the_nautilus": "Breath of the Nautilus",
"enchantment.minecraft.lunge": "Lunge",
"entity.minecraft.camel_husk": "Camel Husk",
"entity.minecraft.nautilus": "Nautilus",
"entity.minecraft.parched": "Parched",
"entity.minecraft.zombie_nautilus": "Zombie Nautilus",
"gamerule.minecraft.elytra_movement_check": "Do elytra movement check",
"gamerule.minecraft.fire_spread_radius_around_player": "Fire spread radius",
"gamerule.minecraft.fire_spread_radius_around_player.description": "The radius in blocks around a player in which fire can spread",
"gamerule.minecraft.player_movement_check": "Do player movement check",
"gamerule.minecraft.raids": "Do raids",
"item.intangible": "Intangible",
"item.minecraft.camel_husk_spawn_egg": "Camel Husk Spawn Egg",
"item.minecraft.copper_nautilus_armor": "Copper Nautilus Armor",
"item.minecraft.copper_spear": "Copper Spear",
"item.minecraft.diamond_nautilus_armor": "Diamond Nautilus Armor",
"item.minecraft.diamond_spear": "Diamond Spear",
"item.minecraft.golden_nautilus_armor": "Golden Nautilus Armor",
"item.minecraft.golden_spear": "Golden Spear",
"item.minecraft.iron_nautilus_armor": "Iron Nautilus Armor",
"item.minecraft.iron_spear": "Iron Spear",
"item.minecraft.nautilus_spawn_egg": "Nautilus Spawn Egg",
"item.minecraft.netherite_horse_armor": "Netherite Horse Armor",
"item.minecraft.netherite_nautilus_armor": "Netherite Nautilus Armor",
"item.minecraft.netherite_spear": "Netherite Spear",
"item.minecraft.parched_spawn_egg": "Parched Spawn Egg",
"item.minecraft.stone_spear": "Stone Spear",
"item.minecraft.wooden_spear": "Wooden Spear",
"item.minecraft.zombie_nautilus_spawn_egg": "Zombie Nautilus Spawn Egg",
"key.category.minecraft.debug": "Debug",
"key.debug.clearChat": "Clear Chat",
"key.debug.copyLocation": "Copy Location",
"key.debug.copyRecreateCommand": "Copy Data",
"key.debug.crash": "Debug Crash",
"key.debug.dumpDynamicTextures": "Dump Dynamic Textures",
"key.debug.dumpVersion": "Dump Version Info",
"key.debug.focusPause": "Toggle Lost Focus Pause",
"key.debug.fpsCharts": "FPS Charts",
"key.debug.modifier": "Debug Modifier Key",
"key.debug.networkCharts": "Network Charts",
"key.debug.overlay": "Toggle Overlay",
"key.debug.profiling": "Start/Stop Profiling",
"key.debug.profilingChart": "Profiling Chart",
"key.debug.reloadChunk": "Reload Chunks",
"key.debug.reloadResourcePacks": "Reload Resource Packs",
"key.debug.showAdvancedTooltips": "Show Advanced Tooltips",
"key.debug.showChunkBorders": "Show Chunk Boundaries",
"key.debug.showHitboxes": "Show Hitboxes",
"key.debug.spectate": "Cycle Spectator",
"key.debug.switchGameMode": "Game Mode Switcher",
"key.toggleGui": "Toggle GUI",
"key.toggleSpectatorShaderEffects": "Toggle Spectator Shader Effects",
"mco.backup.entry.worldType.adventureMap": "Adventure Map",
"mco.backup.entry.worldType.experience": "Experience",
"mco.configure.world.name.validation.whitespace": "Must not start or end with whitespace. It will be trimmed.",
"narration.checkbox.usage.focused.check": "Press Enter to check",
"narration.checkbox.usage.focused.uncheck": "Press Enter to uncheck",
"narration.checkbox.usage.hovered.check": "Left click to check",
"narration.checkbox.usage.hovered.uncheck": "Left click to uncheck",
"options.blocks": "%s Blocks",
"options.chunkFade": "Chunk Fade Time",
"options.chunkFade.none": "Chunk Fade: None",
"options.chunkFade.seconds": "Chunk Fade: %s second(s)",
"options.chunkFade.tooltip": "How long in seconds chunks should fade in when they're first rendered, if at all.",
"options.cutoutLeaves": "See-Through Leaves",
"options.cutoutLeaves.tooltip": "Allows you to see through gaps in leaves. Disabling improves performance.",
"options.graphics.preset": "Preset",
"options.graphics.preset.tooltip": "Sets \"Quality & Performance\" settings to reasonable defaults corresponding to the desired quality.",
"options.improvedTransparency": "Improved Transparency",
"options.improvedTransparency.tooltip": "An experimental approach that uses screen shaders for drawing weather, clouds, and particles behind translucent blocks and water.\nThis will impact GPU performance.",
"options.maxAnisotropy": "Anisotropic Filtering",
"options.maxAnisotropy.tooltip": "Each level significantly improves how smooth textures look, but impacts performance and significantly impacts video memory usage. Requires Texture Filtering to be set to Anisotropic.",
"options.musicToast": "Music Toast",
"options.musicToast.never.tooltip": "No music toast is shown.",
"options.musicToast.pauseMenu": "Pause Menu",
"options.musicToast.pauseMenu.tooltip": "A music toast is constantly displayed in the in-game pause menu while a song is playing.",
"options.musicToast.pauseMenuAndToast": "Pause Menu and Toast",
"options.musicToast.pauseMenuAndToast.tooltip": "Displays a toast when a song starts playing. The same toast is constantly displayed in the in-game pause menu while a song is playing.",
"options.textureFiltering": "Texture Filtering",
"options.textureFiltering.anisotropic": "Anisotropic",
"options.textureFiltering.anisotropic.tooltip": "A hardware based filtering method, but impacts performance and significantly impacts video memory usage. May not be supported on all hardware.",
"options.textureFiltering.none.tooltip": "Textures are displayed without any filtering. Blocks may look blurry when viewed at an angle.",
"options.textureFiltering.rgss": "RGSS",
"options.textureFiltering.rgss.tooltip": "(Rotated Grid Super Sampling)\nA shader based filtering method that improves texture quality with a moderate performance impact.",
"options.video.display.header": "Display",
"options.video.interface.header": "Interface",
"options.video.preferences.header": "Preferences",
"options.video.quality.header": "Quality & Performance",
"options.vignette": "Show Vignette",
"options.vignette.tooltip": "This is a subtle texture over the game screen used for reducing brightness towards the edges of the screen and warning about the world border.",
"options.weatherRadius": "Weather Effect Radius",
"options.weatherRadius.tooltip": "Radius of the area where rain and snow effects are visible. Very low performance impact.",
"stat.minecraft.nautilus_one_cm": "Distance by Nautilus",
"subtitles.entity.baby_nautilus.ambient": "Baby Nautilus chitters",
"subtitles.entity.baby_nautilus.ambient_land": "Baby Nautilus chitters",
"subtitles.entity.baby_nautilus.death": "Baby Nautilus dies",
"subtitles.entity.baby_nautilus.death_land": "Baby Nautilus dies",
"subtitles.entity.baby_nautilus.eat": "Baby Nautilus eats",
"subtitles.entity.baby_nautilus.hurt": "Baby Nautilus hurts",
"subtitles.entity.baby_nautilus.hurt_land": "Baby Nautilus hurts",
"subtitles.entity.baby_nautilus.swim": "Baby Nautilus swims",
"subtitles.entity.camel_husk.ambient": "Camel Husk grumphs",
"subtitles.entity.camel_husk.dash": "Camel Husk yeets",
"subtitles.entity.camel_husk.dash_ready": "Camel Husk recovers",
"subtitles.entity.camel_husk.death": "Camel Husk dies",
"subtitles.entity.camel_husk.eat": "Camel Husk eats",
"subtitles.entity.camel_husk.hurt": "Camel Husk hurts",
"subtitles.entity.camel_husk.sit": "Camel Husk sits down",
"subtitles.entity.camel_husk.stand": "Camel Husk stands up",
"subtitles.entity.nautilus.ambient": "Nautilus clacks",
"subtitles.entity.nautilus.ambient_land": "Nautilus clacks",
"subtitles.entity.nautilus.dash": "Nautilus jets",
"subtitles.entity.nautilus.dash_land": "Nautilus jets",
"subtitles.entity.nautilus.dash_ready": "Nautilus recovers",
"subtitles.entity.nautilus.dash_ready_land": "Nautilus recovers",
"subtitles.entity.nautilus.death": "Nautilus dies",
"subtitles.entity.nautilus.death_land": "Nautilus dies",
"subtitles.entity.nautilus.eat": "Nautilus eats",
"subtitles.entity.nautilus.hurt": "Nautilus hurts",
"subtitles.entity.nautilus.hurt_land": "Nautilus hurts",
"subtitles.entity.nautilus.swim": "Nautilus swims",
"subtitles.entity.parched.ambient": "Parched crackles",
"subtitles.entity.parched.death": "Parched dies",
"subtitles.entity.parched.hurt": "Parched hurts",
"subtitles.entity.parrot.imitate.camel_husk": "Parrot grumphs",
"subtitles.entity.parrot.imitate.parched": "Parrot crackles",
"subtitles.entity.parrot.imitate.zombie_nautilus": "Parrot gargles",
"subtitles.entity.zombie_horse.angry": "Zombie Horse neighs",
"subtitles.entity.zombie_horse.eat": "Zombie Horse eats",
"subtitles.entity.zombie_nautilus.ambient": "Zombie Nautilus burbles",
"subtitles.entity.zombie_nautilus.ambient_land": "Zombie Nautilus burbles",
"subtitles.entity.zombie_nautilus.dash": "Zombie Nautilus jets",
"subtitles.entity.zombie_nautilus.dash_land": "Zombie Nautilus jets",
"subtitles.entity.zombie_nautilus.dash_ready": "Zombie Nautilus recovers",
"subtitles.entity.zombie_nautilus.dash_ready_land": "Zombie Nautilus recovers",
"subtitles.entity.zombie_nautilus.death": "Zombie Nautilus dies",
"subtitles.entity.zombie_nautilus.death_land": "Zombie Nautilus dies",
"subtitles.entity.zombie_nautilus.eat": "Zombie Nautilus eats",
"subtitles.entity.zombie_nautilus.hurt": "Zombie Nautilus hurts",
"subtitles.entity.zombie_nautilus.hurt_land": "Zombie Nautilus hurts",
"subtitles.entity.zombie_nautilus.swim": "Zombie Nautilus swims",
"subtitles.item.armor.equip_nautilus": "Nautilus Armor equips",
"subtitles.item.armor.unequip_nautilus": "Nautilus Armor unequips",
"subtitles.item.spear_wood.attack": "Spear jabs",
"subtitles.item.spear_wood.hit": "Spear hits",
"subtitles.item.spear_wood.use": "Charges with Spear",
"subtitles.item.spear.attack": "Spear jabs",
"subtitles.item.spear.hit": "Spear hits",
"subtitles.item.spear.lunge": "Spear lunges",
"subtitles.item.spear.use": "Charges with Spear"
},
"1.21.9": {
"advMode.notEnabled.spawner": "Spawner blocks are not enabled",
"block.minecraft.acacia_shelf": "Acacia Shelf",
+3 -3
View File
@@ -1,8 +1,8 @@
projectVersion=5.5.0
projectVersion=5.6.0
# Smile emoji (note that modrinth may not have added the version on release yet)
mcVersions=1.21.9, 1.21.8, 1.21.7, 1.21.6, 1.21.5, 1.21.4, 1.21.3, 1.21.2, 1.21.1, 1.21, 1.20.6, 1.20.5, 1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10
mcVersionRange=1.10-1.21.9
mcVersions=1.21.11, 1.21.10, 1.21.9, 1.21.8, 1.21.7, 1.21.6, 1.21.5, 1.21.4, 1.21.3, 1.21.2, 1.21.1, 1.21, 1.20.6, 1.20.5, 1.20.4, 1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10
mcVersionRange=1.10-1.21.11
velocityVersion=3.4
org.gradle.configureondemand=true
+2 -2
View File
@@ -3,7 +3,7 @@ metadata.format.version = "1.1"
[versions]
# ViaVersion
viaver = "5.5.0"
viaver = "5.6.0"
# Common provided
netty = "4.0.20.Final"
@@ -16,7 +16,7 @@ checkerQual = "3.51.0"
paper = "1.16.5-R0.1-SNAPSHOT"
velocity = "3.1.1"
fabricLoader = "0.11.6"
viaProxy = "3.4.5-SNAPSHOT"
viaProxy = "3.4.7-SNAPSHOT"
[libraries]
Binary file not shown.
+2 -2
View File
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=a17ddd85a26b6a7f5ddb71ff8b05fc5104c0202c6e64782429790c933686c806
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
distributionSha256Sum=72f44c9f8ebcb1af43838f45ee5c4aa9c5444898b3468ab3f4af7b6076c5bc3f
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
@@ -47,7 +47,7 @@
},
{
"id": "viaversion",
"version": "[5.5.0-SNAPSHOT,)"
"version": "[5.6.0-SNAPSHOT,)"
}
]
},
+1 -1
View File
@@ -1,5 +1,5 @@
plugins {
id("io.papermc.hangar-publish-plugin") version "0.1.3"
id("io.papermc.hangar-publish-plugin") version "0.1.4"
id("com.modrinth.minotaur") version "2.+"
// A nice no-conflict comment for patching in downgrading