Compare commits

..
43 Commits
Author SHA1 Message Date
Nassim Jahnke 917427c940 5.5.0 Release 2025-10-03 13:48:04 +02:00
Nassim Jahnke b7ddc108f5 Prepare for the release later 2025-10-03 08:18:06 +02:00
FlorianMichael db65302112 Write empty tag if no shoulder data is present 2025-10-02 18:13:42 +02:00
FlorianMichael 795b195690 Use translation keys for code of conduct dialog 2025-10-02 14:25:23 +02:00
Nassim Jahnke b7c42f9b2e Cancel mannequin data from unknown entities 2025-09-30 18:29:04 +02:00
Nassim Jahnke 1a0c79c46a Add 1.21.9 translations 2025-09-30 18:05:04 +02:00
Nassim Jahnke 95d809f53a Update item_model use 2025-09-30 14:37:36 +02:00
FlorianMichael f8c249f2c2 Only register open screen translatable rewriter 2025-09-26 20:41:01 +02:00
FlorianMichael fe890fa59e Handle relative player rotations 2025-09-25 17:03:31 +02:00
Nassim Jahnke 9806afed99 Handle SET_DEFAULT_SPAW_POSITION change 2025-09-25 16:59:57 +02:00
Nassim Jahnke 432c669daf 1.21.9-pre1 2025-09-25 16:59:57 +02:00
Nassim Jahnke 838d83897b Start emulating mannequins via players 2025-09-25 16:59:57 +02:00
Nassim Jahnke e10c73138d 25w37a 2025-09-25 16:59:57 +02:00
FlorianMichael e0892faf13 Show server code of conduct as dialog screen 2025-09-25 16:59:57 +02:00
Nassim Jahnke c03cb66bbd wip 25w36a/b 2025-09-25 16:59:56 +02:00
Nassim Jahnke ea1d86642e 25w35a 2025-09-25 16:59:56 +02:00
Nassim Jahnke 6c9c7288c4 25w34b 2025-09-25 16:59:56 +02:00
Nassim Jahnke 8dab7f7284 25w33a 2025-09-25 16:59:56 +02:00
Nassim Jahnke f0c16003e0 25w32a 2025-09-25 16:59:56 +02:00
Nassim Jahnke 4d4b18b80e 25w31a 2025-09-25 16:59:56 +02:00
Nassim Jahnke 99abab0d62 Update dependencies 2025-09-20 22:39:48 +02:00
EnZaXD f7656fb45f Always remap show_dialog/custom click events (#1104) 2025-09-18 20:03:13 +02:00
EnZaXD 6a440aaeda Handle signed chat commands as well for custom click events (#1103) 2025-09-18 20:02:42 +02:00
EnZaXD 075ca7044d Make some functions protected in ChestDialogViewProvider (#1101) 2025-09-16 21:31:56 +02:00
EnZaXD a8cd653a7a Remove serialize versions from item hasher (#1102) 2025-09-16 21:31:51 +02:00
EnZaXD 191dd24117 Add missing sound name handlers for biomes (#1098) 2025-09-13 10:08:02 +02:00
EnZaXD 6ad05d8bc2 Null check chest dialog storage in ChestDialogViewProvider#closeDialog (#1097) 2025-09-12 21:14:54 +02:00
Nassim Jahnke c5a2a6ae6e Reset player position storage on respawn 2025-09-03 17:11:41 +02:00
EnZaXD 31f7f4edc1 Rename ProtocolRunnable, always submit tick logic into event loop (#1093) 2025-09-03 17:08:08 +02:00
purpurcof b2a2712949 Fix reading any NBT type for SERVER_LINKS (#1092) 2025-09-01 17:31:05 +02:00
EnZaXD 7bd6a849a3 Fix SOUND_ENTITY remap not working for the player in 1.14->1.13.2 (#1086) 2025-09-01 16:30:33 +02:00
riku6460 473b4af0d0 Add missing check whether the player is set in client tick emulation 1.21.2->1.21 (#1090) 2025-08-29 17:16:07 +02:00
dependabot[bot] b7c8891497 Bump actions/setup-java from 4 to 5 (#1089)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-26 15:36:00 +02:00
Nassim Jahnke be5344b3e4 Reassign item on handleItemToClient calls
Needed in rewriters before 1.20 with a recent change; the rest weren't technically necessary
2025-08-22 20:10:10 +02:00
Nassim Jahnke cc4ea71722 Fix custom name in banners etc. in 1.21.5->1.21.4 2025-08-17 16:37:16 +02:00
EnZaXD f288f2d716 Add dialog styling options (#1072) 2025-08-17 08:16:42 +02:00
dependabot[bot] 61a4cead72 [ci skip] Bump actions/checkout from 4 to 5 (#1080)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-12 08:22:46 +02:00
EnZaXDandNassim Jahnke b9ead8109f [ci skip] Gradle & Shadow 9.0.0; Rewrite .gitignore file (#1075)
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
2025-08-09 14:17:40 +02:00
EnZaXD 12cde18a3d Use ViaBackwardsPlatform#getLogger for protocol logger creation (#1078) 2025-08-08 16:03:40 +02:00
EnZaXD b8adbde876 Add statistic mappings for 1.21.6->1.21.5 (#1077) 2025-08-03 09:34:06 +02:00
EnZaXD 6faf407cc9 Use SerializerVersion.V1_21_6 in 1.21.6->1.21.5 (#1073) 2025-07-31 13:05:01 +02:00
EnZaXD f3f19dfd4e Pass dialog title through component conversion in 1.21.6->.5 (#1074) 2025-07-31 13:04:53 +02:00
EnZaXD 80ed7e1e75 Handle HIDE_ADDITIONAL_TOOLTIP in chat items in 1.21.5->1.21.4 (#1068) 2025-07-31 13:04:42 +02:00
81 changed files with 1565 additions and 357 deletions

No files matched your search

+2 -2
View File
@@ -10,13 +10,13 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 17
+2 -2
View File
@@ -12,13 +12,13 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
persist-credentials: false
- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 17
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
persist-credentials: false
- name: Update Gradle Wrapper
+19 -98
View File
@@ -1,115 +1,36 @@
### Java files ###
*.class
# Gradle
# Package Files
#*.jar
*.war
*.ear
.gradle/
build/
out/
classes/
.kotlin/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# Eclipse
*.launch
# Idea
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
# Ignore project files
*.iml
# Ignore IDEA directory
.idea/*
.idea/
!.idea/copyright/*
!.idea/scopes/*
# Include the project's dictionary
!.idea/dictionaries/
!.idea/dictionaries/*
# File-based project format:
*.iml
*.ipr
*.iws
### Plugin-specific files: ###
# IntelliJ
/out/
# VSCode
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Eclipse ###
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
# Eclipse Core
.vscode/
bin/
.classpath
.project
# External tool builders
.externalToolBuilders/
# macOS
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse
### Maven ###
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
buildNumber.properties
### NetBeans ###
nbproject/private/
build/
nbbuild/
dist/
nbdist/
nbactions.xml
nb-configuration.xml
.nb-gradle/
### MacOS ###
.DS_Store
### Run Folder (ViaProxy) ###
common/run/
# Misc
run/
+3 -1
View File
@@ -8,5 +8,7 @@ repositories {
dependencies {
// version must be manually kept in sync with the one in root project settings.gradle.kts
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.8")
implementation("com.gradleup.shadow:shadow-gradle-plugin:9.1.0")
// A nice no-conflict comment for patching in downgrading
}
@@ -8,7 +8,7 @@ tasks {
val ver = project.version.toString()
val desc = project.description
filesMatching(listOf("plugin.yml", "META-INF/sponge_plugins.json", "fabric.mod.json")) {
expand("version" to ver, "description" to desc)
expand(mapOf("version" to ver, "description" to desc))
}
}
javadoc {
@@ -18,6 +18,7 @@ tasks {
compileJava {
options.encoding = Charsets.UTF_8.name()
options.compilerArgs.addAll(listOf("-nowarn", "-Xlint:-unchecked", "-Xlint:-deprecation"))
options.isFork = true
}
}
@@ -14,6 +14,7 @@ tasks {
from(project.rootProject.file("LICENSE"))
}
val shadowJar = named<ShadowJar>("shadowJar") {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
archiveClassifier.set("")
configureRelocations()
}
+1 -1
View File
@@ -30,7 +30,7 @@ java {
val prepareViaProxyFiles by tasks.registering(Copy::class) {
dependsOn(project.tasks.shadowJar)
from(project.tasks.shadowJar.get().archiveFile.get().asFile)
from(project.tasks.shadowJar.map { it.archiveFile.get().asFile })
into(layout.projectDirectory.dir("run/jars"))
val projectName = project.name
@@ -17,7 +17,10 @@
*/
package com.viaversion.viabackwards;
import com.viaversion.viabackwards.api.DialogStyleConfig;
import com.viaversion.viaversion.util.ChatColorUtil;
import com.viaversion.viaversion.util.Config;
import com.viaversion.viaversion.util.ConfigSection;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
@@ -41,6 +44,7 @@ public class ViaBackwardsConfig extends Config implements com.viaversion.viaback
private boolean mapCustomModelData;
private boolean mapDisplayEntities;
private boolean suppressEmulationWarnings;
private DialogStyleConfig dialogStyleConfig;
public ViaBackwardsConfig(File configFile, Logger logger) {
super(configFile, logger);
@@ -66,6 +70,29 @@ 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);
dialogStyleConfig = loadDialogStyleConfig(getSection("dialog-style"));
}
private DialogStyleConfig loadDialogStyleConfig(final ConfigSection section) {
return new DialogStyleConfig(
getString(section, "page-navigation-title", "&9&lPage navigation"),
getString(section, "page-navigation-next", "&9Left click: &6Go to next page"),
getString(section, "page-navigation-previous", "&9Right click: &6Go to previous page"),
getString(section, "increase-value", "&9Left click: &6Increase value by %s"),
getString(section, "decrease-value", "&9Right click: &6Decrease value by %s"),
getString(section, "value-range", "&7(Value between &a%s &7and &a%s&7)"),
getString(section, "next-option", "&9Left click: &6Go to next option"),
getString(section, "previous-option", "&9Right click: &6Go to previous option"),
getString(section, "current-value", "&7Current value: &a%s"),
getString(section, "edit-value", "&9Left click: &6Edit text"),
getString(section, "set-text", "&9Left click/close: &6Set text"),
getString(section, "close", "&9Left click: &6Close"),
getString(section, "toggle-value", "&9Left click: &6Toggle value")
);
}
protected String getString(final ConfigSection section, final String key, final String def) {
return ChatColorUtil.translateAlternateColorCodes(section.getString(key, def));
}
@Override
@@ -133,6 +160,11 @@ public class ViaBackwardsConfig extends Config implements com.viaversion.viaback
return suppressEmulationWarnings;
}
@Override
public DialogStyleConfig dialogStyleConfig() {
return dialogStyleConfig;
}
@Override
public URL getDefaultConfigURL() {
return getClass().getClassLoader().getResource("assets/viabackwards/config.yml");
@@ -19,11 +19,13 @@ package com.viaversion.viabackwards.api;
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
import com.viaversion.viabackwards.api.rewriters.text.TranslatableRewriter;
import com.viaversion.viabackwards.utils.BackwardsProtocolLogger;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.util.ProtocolLogger;
import org.checkerframework.checker.nullness.qual.Nullable;
public abstract class BackwardsProtocol<CU extends ClientboundPacketType, CM extends ClientboundPacketType, SM extends ServerboundPacketType, SU extends ServerboundPacketType>
@@ -54,6 +56,11 @@ public abstract class BackwardsProtocol<CU extends ClientboundPacketType, CM ext
}
}
@Override
protected ProtocolLogger createLogger() {
return new BackwardsProtocolLogger(getClass());
}
@Override
public boolean hasMappingDataToLoad() {
// Manually load them later, since they depend on VV's mappings
@@ -0,0 +1,25 @@
/*
* 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.api;
public record DialogStyleConfig(String pageNavigationTitle, String pageNavigationNext, String pageNavigationPrevious,
String increaseValue, String decreaseValue, String valueRange, String nextOption,
String previousOption, String currentValue, String editValue, String setText,
String close, String toggleValue) {
}
@@ -112,4 +112,11 @@ public interface ViaBackwardsConfig extends Config {
* @return true if enabled
*/
boolean suppressEmulationWarnings();
/**
* Returns the dialog style configuration.
*
* @return the dialog style configuration
*/
DialogStyleConfig dialogStyleConfig();
}
@@ -62,6 +62,7 @@ import com.viaversion.viabackwards.protocol.v1_21_5to1_21_4.Protocol1_21_5To1_21
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.task.ChestDialogViewTask;
import com.viaversion.viabackwards.protocol.v1_21_7to1_21_6.Protocol1_21_7To1_21_6;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.Protocol1_21_9To1_21_7;
import com.viaversion.viabackwards.protocol.v1_21to1_20_5.Protocol1_21To1_20_5;
import com.viaversion.viabackwards.protocol.v1_9_1to1_9.Protocol1_9_1To1_9;
import com.viaversion.viabackwards.protocol.v1_9_3to1_9_1.Protocol1_9_3To1_9_1;
@@ -76,7 +77,7 @@ import java.util.logging.Logger;
public interface ViaBackwardsPlatform {
String MINIMUM_VV_VERSION = "5.4.0";
String MINIMUM_VV_VERSION = "5.5.0";
/**
* Initialize ViaBackwards.
@@ -154,6 +155,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);
}
default void enable() {
@@ -47,7 +47,10 @@ public class EntityPositionHandler {
}
public void cacheEntityPosition(PacketWrapper wrapper, double x, double y, double z, boolean create, boolean relative) {
int entityId = wrapper.get(Types.VAR_INT, 0);
cacheEntityPosition(wrapper, wrapper.get(Types.VAR_INT, 0), x, y, z, create, relative);
}
public void cacheEntityPosition(PacketWrapper wrapper, int entityId, double x, double y, double z, boolean create, boolean relative) {
StoredEntityData storedEntity = entityRewriter.tracker(wrapper.user()).entityData(entityId);
if (storedEntity == null) {
if (Via.getManager().isDebug()) { // There is too many plugins violating this out there, and reading seems to be hard! :>
@@ -132,7 +132,7 @@ public class BackwardsItemRewriter<C extends ClientboundPacketType, S extends Se
public @Nullable Item handleItemToServer(UserConnection connection, @Nullable Item item) {
if (item == null) return null;
super.handleItemToServer(connection, item);
item = super.handleItemToServer(connection, item);
if (item.tag() != null) {
Tag originalId = item.tag().remove(nbtTagName("id"));
if (originalId instanceof IntTag) {
@@ -47,7 +47,7 @@ public abstract class BackwardsItemRewriterBase<C extends ClientboundPacketType,
@Override
public @Nullable Item handleItemToServer(UserConnection connection, @Nullable Item item) {
if (item == null) return null;
super.handleItemToServer(connection, item);
item = super.handleItemToServer(connection, item);
restoreDisplayTag(item);
return item;
@@ -18,10 +18,11 @@
package com.viaversion.viabackwards.api.rewriters;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.StringTag;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.RegistryEntry;
import com.viaversion.viaversion.rewriter.RegistryDataRewriter;
import com.viaversion.viaversion.util.Key;
public class BackwardsRegistryRewriter extends RegistryDataRewriter {
@@ -32,6 +33,22 @@ public class BackwardsRegistryRewriter extends RegistryDataRewriter {
this.protocol = protocol;
}
@Override
public RegistryEntry[] handle(final UserConnection connection, final String key, final RegistryEntry[] entries) {
if (Key.stripMinecraftNamespace(key).equals("worldgen/biome")) {
for (final RegistryEntry entry : entries) {
final CompoundTag biome = (CompoundTag) entry.tag();
if (biome == null) {
continue;
}
final CompoundTag effects = biome.getCompoundTag("effects");
updateBiomeEffects(effects);
}
}
return super.handle(connection, key, entries);
}
@Override
public void updateJukeboxSongs(final RegistryEntry[] entries) {
for (final RegistryEntry entry : entries) {
@@ -39,13 +56,36 @@ public class BackwardsRegistryRewriter extends RegistryDataRewriter {
continue;
}
final StringTag soundEvent = ((CompoundTag) entry.tag()).getStringTag("sound_event");
if (soundEvent != null) {
final String mappedNamedSound = protocol.getMappingData().getMappedNamedSound(soundEvent.getValue());
if (mappedNamedSound != null) {
soundEvent.setValue(mappedNamedSound);
}
}
updateSound((CompoundTag) entry.tag(), "sound_event");
}
}
private void updateBiomeEffects(final CompoundTag effects) {
updateSound(effects.getCompoundTag("mood_sound"), "sound");
updateSound(effects.getCompoundTag("additions_sound"), "sound");
updateSound(effects.getCompoundTag("music"), "sound");
updateSound(effects, "ambient_sound");
}
private void updateSound(final CompoundTag tag, final String name) {
if (tag == null) {
return;
}
final String sound = tag.getString(name);
if (sound == null) {
return;
}
final String mappedSound = protocol.getMappingData().getMappedNamedSound(sound);
if (mappedSound == null) {
return;
}
if (mappedSound.isEmpty()) {
tag.putString(name, "minecraft:intentionally_empty");
} else {
tag.putString(name, mappedSound);
}
}
}
@@ -208,9 +208,9 @@ public abstract class LegacyBlockItemRewriter<C extends ClientboundPacketType, S
}
@Override
public @Nullable Item handleItemToServer(UserConnection connection, @Nullable final Item item) {
public @Nullable Item handleItemToServer(UserConnection connection, @Nullable Item item) {
if (item == null) return null;
super.handleItemToServer(connection, item);
item = super.handleItemToServer(connection, item);
if (item.tag() != null) {
Tag originalId = item.tag().remove(nbtTagName("id"));
if (originalId instanceof IntTag) {
@@ -86,7 +86,7 @@ public abstract class LegacyEntityRewriter<C extends ClientboundPacketType, T ex
clientWorld.setEnvironment(wrapper.get(Types.INT, 1));
final int entityId = wrapper.get(Types.INT, 0);
addTrackedEntity(wrapper, entityId, playerType);
tracker(wrapper.user()).addEntity(entityId, playerType);
tracker(wrapper.user()).setClientEntityId(entityId);
});
}
@@ -131,13 +131,13 @@ public abstract class LegacyEntityRewriter<C extends ClientboundPacketType, T ex
return;
}
addTrackedEntity(wrapper, wrapper.get(Types.VAR_INT, 0), type);
tracker(wrapper.user()).addEntity(wrapper.get(Types.VAR_INT, 0), type);
};
}
protected PacketHandler getTrackerAndDataHandler(Type<List<EntityData>> dataType, EntityType entityType) {
return wrapper -> {
addTrackedEntity(wrapper, wrapper.get(Types.VAR_INT, 0), entityType);
tracker(wrapper.user()).addEntity(wrapper.get(Types.VAR_INT, 0), entityType);
List<EntityData> entityDataList = wrapper.get(dataType, 0);
handleEntityData(wrapper.get(Types.VAR_INT, 0), entityDataList, wrapper.user());
};
@@ -162,11 +162,6 @@ public abstract class LegacyEntityRewriter<C extends ClientboundPacketType, T ex
};
}
@Deprecated
protected void addTrackedEntity(PacketWrapper wrapper, int entityId, EntityType type) {
tracker(wrapper.user()).addEntity(entityId, type);
}
@FunctionalInterface
protected interface IdSetter {
@@ -38,7 +38,7 @@ final class EntityPacketRewriter1_99 extends EntityRewriter<ClientboundPacket1_2
@Override
public void registerPackets() {
registerTrackerWithData1_19(ClientboundPackets1_21_2.ADD_ENTITY, EntityTypes1_21_4.FALLING_BLOCK);
registerTrackerWithData1_21_9(ClientboundPackets1_21_2.ADD_ENTITY, EntityTypes1_21_4.FALLING_BLOCK);
registerSetEntityData(ClientboundPackets1_21_2.SET_ENTITY_DATA);
registerRemoveEntities(ClientboundPackets1_21_2.REMOVE_ENTITIES);
registerPlayerAbilities(ClientboundPackets1_21_2.PLAYER_ABILITIES);
@@ -52,7 +52,6 @@ import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
// ServerboundConfigurationPackets1_20_5
// EntityTypes1_21_4 (UNMAPPED type)
// VersionedTypes.V1_21_5
// SerializerVersion.V1_21_5
// 1.99, 1.98
final class Protocol1_99To1_98 extends BackwardsProtocol<ClientboundPacket1_21_2, ClientboundPacket1_21_2, ServerboundPacket1_21_4, ServerboundPacket1_21_4> {
@@ -100,13 +99,13 @@ final class Protocol1_99To1_98 extends BackwardsProtocol<ClientboundPacket1_21_2
// If needed for any particle, item, or block changes. Extend ParticleRewriter for particle serializer changes
particleRewriter.registerLevelParticles1_21_4(ClientboundPackets1_21_2.LEVEL_PARTICLES);
particleRewriter.registerExplode1_21_2(ClientboundPackets1_21_2.EXPLODE);
particleRewriter.registerExplode1_21_9(ClientboundPackets1_21_2.EXPLODE);
}
@Override
public void init(final UserConnection connection) {
addEntityTracker(connection, new EntityTrackerBase(connection, EntityTypes1_21_4.PLAYER));
addItemHasher(connection, new ItemHasherBase(this, connection, SerializerVersion.V1_21_5, SerializerVersion.V1_21_5));
addItemHasher(connection, new ItemHasherBase(this, connection));
}
@Override
@@ -71,7 +71,7 @@ public class ItemPacketRewriter1_11_1 extends LegacyBlockItemRewriter<Clientboun
@Override
public Item handleItemToServer(UserConnection connection, Item item) {
if (item == null) return null;
super.handleItemToServer(connection, item);
item = super.handleItemToServer(connection, item);
enchantmentRewriter.handleToServer(item);
return item;
@@ -280,7 +280,7 @@ public class BlockItemPacketRewriter1_11 extends LegacyBlockItemRewriter<Clientb
@Override
public Item handleItemToServer(UserConnection connection, Item item) {
if (item == null) return null;
super.handleItemToServer(connection, item);
item = super.handleItemToServer(connection, item);
CompoundTag tag = item.tag();
if (tag == null) return item;
@@ -238,7 +238,7 @@ public class BlockItemPacketRewriter1_12 extends LegacyBlockItemRewriter<Clientb
@Override
public @Nullable Item handleItemToServer(UserConnection connection, Item item) {
if (item == null) return null;
super.handleItemToServer(connection, item);
item = super.handleItemToServer(connection, item);
if (item.tag() != null) {
if (item.tag().remove("Via|LongArrayTags") instanceof CompoundTag tag) {
@@ -90,16 +90,11 @@ public class Protocol1_13_1To1_13 extends BackwardsProtocol<ClientboundPackets1_
}
});
registerServerbound(ServerboundPackets1_13.EDIT_BOOK, new PacketHandlers() {
@Override
public void register() {
map(Types.ITEM1_13);
map(Types.BOOLEAN);
handler(wrapper -> {
itemRewriter.handleItemToServer(wrapper.user(), wrapper.get(Types.ITEM1_13, 0));
wrapper.write(Types.VAR_INT, 0);
});
}
registerServerbound(ServerboundPackets1_13.EDIT_BOOK, wrapper -> {
final Item item = itemRewriter.handleItemToServer(wrapper.user(), wrapper.read(Types.ITEM1_13));
wrapper.write(Types.ITEM1_13, item);
wrapper.passthrough(Types.BOOLEAN);
wrapper.write(Types.VAR_INT, 0);
});
registerClientbound(ClientboundPackets1_13.OPEN_SCREEN, new PacketHandlers() {
@@ -181,8 +176,8 @@ public class Protocol1_13_1To1_13 extends BackwardsProtocol<ClientboundPackets1_
if (wrapper.passthrough(Types.BOOLEAN)) {
wrapper.passthrough(Types.COMPONENT); // Title
wrapper.passthrough(Types.COMPONENT); // Description
Item icon = wrapper.passthrough(Types.ITEM1_13);
itemRewriter.handleItemToClient(wrapper.user(), icon);
Item icon = itemRewriter.handleItemToClient(wrapper.user(), wrapper.read(Types.ITEM1_13));
wrapper.write(Types.ITEM1_13, icon);
wrapper.passthrough(Types.VAR_INT); // Frame type
int flags = wrapper.passthrough(Types.INT); // Flags
if ((flags & 1) != 0)
@@ -201,7 +196,9 @@ public class Protocol1_13_1To1_13 extends BackwardsProtocol<ClientboundPackets1_
});
tagRewriter.register(ClientboundPackets1_13.UPDATE_TAGS, RegistryType.ITEM);
new StatisticsRewriter<>(this).register(ClientboundPackets1_13.AWARD_STATS);
new StatisticsRewriter<>(this).
register(ClientboundPackets1_13.AWARD_STATS);
}
@Override
@@ -43,18 +43,12 @@ public class ItemPacketRewriter1_13_1 extends ItemRewriter<ClientboundPackets1_1
int size = wrapper.passthrough(Types.UNSIGNED_BYTE);
for (int i = 0; i < size; i++) {
//Input Item
Item input = wrapper.passthrough(Types.ITEM1_13);
handleItemToClient(wrapper.user(), input);
//Output Item
Item output = wrapper.passthrough(Types.ITEM1_13);
handleItemToClient(wrapper.user(), output);
passthroughClientboundItem(wrapper); // Input
passthroughClientboundItem(wrapper); // Output
boolean secondItem = wrapper.passthrough(Types.BOOLEAN); //Has second item
if (secondItem) {
//Second Item
Item second = wrapper.passthrough(Types.ITEM1_13);
handleItemToClient(wrapper.user(), second);
passthroughClientboundItem(wrapper); // Second item
}
wrapper.passthrough(Types.BOOLEAN); //Trade disabled
@@ -32,6 +32,7 @@ import com.viaversion.viabackwards.protocol.v1_13to1_12_2.storage.BackwardsBlock
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.storage.NoteBlockStorage;
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.storage.PlayerPositionStorage1_13;
import com.viaversion.viabackwards.protocol.v1_13to1_12_2.storage.TabCompleteStorage;
import com.viaversion.viabackwards.utils.BackwardsProtocolLogger;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
@@ -53,7 +54,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class Protocol1_13To1_12_2 extends BackwardsProtocol<ClientboundPackets1_13, ClientboundPackets1_12_1, ServerboundPackets1_13, ServerboundPackets1_12_1> {
public static final BackwardsMappingData1_13 MAPPINGS = new BackwardsMappingData1_13();
public static final ProtocolLogger LOGGER = new ProtocolLogger(Protocol1_13To1_12_2.class);
public static final ProtocolLogger LOGGER = new BackwardsProtocolLogger(Protocol1_13To1_12_2.class);
private final EntityPacketRewriter1_13 entityRewriter = new EntityPacketRewriter1_13(this);
private final BlockItemPacketRewriter1_13 blockItemPackets = new BlockItemPacketRewriter1_13(this);
private final JsonNBTComponentRewriter<ClientboundPackets1_13> translatableRewriter = new JsonNBTComponentRewriter<>(this, ComponentRewriterBase.ReadType.JSON) {
@@ -260,8 +260,8 @@ public class BlockItemPacketRewriter1_13 extends BackwardsItemRewriter<Clientbou
handler(wrapper -> {
final Item[] items = wrapper.get(Types.ITEM1_8_SHORT_ARRAY, 0);
for (Item item : items) {
handleItemToClient(wrapper.user(), item);
for (int i = 0; i < items.length; i++) {
items[i] = handleItemToClient(wrapper.user(), items[i]);
}
});
}
@@ -272,9 +272,7 @@ public class BlockItemPacketRewriter1_13 extends BackwardsItemRewriter<Clientbou
public void register() {
map(Types.BYTE);
map(Types.SHORT);
map(Types.ITEM1_13, Types.ITEM1_8);
handler(wrapper -> handleItemToClient(wrapper.user(), wrapper.get(Types.ITEM1_8, 0)));
handler(wrapper -> passthroughClientboundItem(wrapper));
}
});
@@ -427,9 +425,7 @@ public class BlockItemPacketRewriter1_13 extends BackwardsItemRewriter<Clientbou
public void register() {
map(Types.VAR_INT);
map(Types.VAR_INT);
map(Types.ITEM1_13, Types.ITEM1_8);
handler(wrapper -> handleItemToClient(wrapper.user(), wrapper.get(Types.ITEM1_8, 0)));
handler(wrapper -> passthroughClientboundItem(wrapper));
}
});
@@ -505,7 +501,7 @@ public class BlockItemPacketRewriter1_13 extends BackwardsItemRewriter<Clientbou
if (rawId == null) {
// Look for custom mappings
super.handleItemToClient(connection, item);
item = super.handleItemToClient(connection, item);
// Handle one-way special case
if (item.identifier() == -1) {
@@ -798,7 +794,7 @@ public class BlockItemPacketRewriter1_13 extends BackwardsItemRewriter<Clientbou
// Handle custom mappings
int identifier = item.identifier();
item.setIdentifier(rawId);
super.handleItemToServer(connection, item);
item = super.handleItemToServer(connection, item);
// Mapped with original data, we can return here
if (item.identifier() != rawId && item.identifier() != -1) return item;
@@ -223,9 +223,8 @@ public class BlockItemPacketRewriter1_14 extends BackwardsItemRewriter<Clientbou
public void register() {
map(Types.VAR_INT); // 0 - Entity ID
map(Types.VAR_INT); // 1 - Slot ID
map(Types.ITEM1_13_2); // 2 - Item
handler(wrapper -> handleItemToClient(wrapper.user(), wrapper.get(Types.ITEM1_13_2, 0)));
handler(wrapper -> passthroughClientboundItem(wrapper));
handler(wrapper -> {
int entityId = wrapper.get(Types.VAR_INT, 0);
@@ -460,7 +459,7 @@ public class BlockItemPacketRewriter1_14 extends BackwardsItemRewriter<Clientbou
@Override
public Item handleItemToClient(UserConnection connection, Item item) {
if (item == null) return null;
super.handleItemToClient(connection, item);
item = super.handleItemToClient(connection, item);
// Lore now uses JSON
final CompoundTag display = item.tag() != null ? item.tag().getCompoundTag("display") : null;
@@ -516,7 +515,7 @@ public class BlockItemPacketRewriter1_14 extends BackwardsItemRewriter<Clientbou
enchantmentRewriter.handleToServer(item);
// Call this last to check for the backup lore above
super.handleItemToServer(connection, item);
item = super.handleItemToServer(connection, item);
return item;
}
}
@@ -25,6 +25,7 @@ import com.viaversion.viabackwards.protocol.v1_14to1_13_2.storage.ChunkLightStor
import com.viaversion.viabackwards.protocol.v1_14to1_13_2.storage.DifficultyStorage;
import com.viaversion.viabackwards.protocol.v1_14to1_13_2.storage.EntityPositionStorage1_14;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.data.entity.StoredEntityData;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.minecraft.ClientWorld;
import com.viaversion.viaversion.api.minecraft.Particle;
@@ -34,11 +35,13 @@ import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_13;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_14;
import com.viaversion.viaversion.api.minecraft.entitydata.EntityData;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.Types1_13_2;
import com.viaversion.viaversion.api.type.types.version.Types1_14;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ClientboundPackets1_13;
import com.viaversion.viaversion.protocols.v1_12_2to1_13.packet.ServerboundPackets1_13;
import com.viaversion.viaversion.protocols.v1_13_2to1_14.packet.ClientboundPackets1_14;
import com.viaversion.viaversion.rewriter.entitydata.EntityDataHandler;
@@ -50,20 +53,6 @@ public class EntityPacketRewriter1_14 extends LegacyEntityRewriter<ClientboundPa
super(protocol, Types1_13_2.ENTITY_DATA_TYPES.optionalComponentType, Types1_13_2.ENTITY_DATA_TYPES.booleanType);
}
//TODO work the method into this class alone
@Override
protected void addTrackedEntity(PacketWrapper wrapper, int entityId, EntityType type) {
super.addTrackedEntity(wrapper, entityId, type);
// Cache the position for every newly tracked entity
if (type == EntityTypes1_14.PAINTING) {
final BlockPosition position = wrapper.get(Types.BLOCK_POSITION1_8, 0);
positionHandler.cacheEntityPosition(wrapper, position.x(), position.y(), position.z(), true, false);
} else if (wrapper.getId() != ClientboundPackets1_14.LOGIN.getId()) { // ignore join game
positionHandler.cacheEntityPosition(wrapper, true, false);
}
}
@Override
protected void registerPackets() {
positionHandler = new EntityPositionHandler(this, EntityPositionStorage1_14.class, EntityPositionStorage1_14::new);
@@ -133,7 +122,17 @@ public class EntityPacketRewriter1_14 extends LegacyEntityRewriter<ClientboundPa
map(Types.SHORT); // 10 - Velocity Y
map(Types.SHORT); // 11 - Velocity Z
handler(getObjectTrackerHandler());
handler(wrapper -> {
final int type = wrapper.get(Types.BYTE, 0);
final int data = wrapper.get(Types.INT, 0);
final EntityType entityType = objectTypeFromId(type, data);
if (entityType == null) {
return;
}
trackAndCacheEntityPosition(wrapper, entityType);
});
handler(wrapper -> {
int id = wrapper.get(Types.BYTE, 0);
@@ -224,7 +223,7 @@ public class EntityPacketRewriter1_14 extends LegacyEntityRewriter<ClientboundPa
handler(wrapper -> {
int type = wrapper.get(Types.VAR_INT, 1);
EntityType entityType = EntityTypes1_14.getTypeFromId(type);
addTrackedEntity(wrapper, wrapper.get(Types.VAR_INT, 0), entityType);
trackAndCacheEntityPosition(wrapper, entityType);
int oldId = newEntityId(type);
if (oldId == -1) {
@@ -252,7 +251,7 @@ public class EntityPacketRewriter1_14 extends LegacyEntityRewriter<ClientboundPa
map(Types.DOUBLE); // Needs to be mapped for the position cache
map(Types.DOUBLE);
map(Types.DOUBLE);
handler(wrapper -> addTrackedEntity(wrapper, wrapper.get(Types.VAR_INT, 0), EntityTypes1_14.EXPERIENCE_ORB));
handler(wrapper -> trackAndCacheEntityPosition(wrapper, EntityTypes1_14.EXPERIENCE_ORB));
}
});
@@ -264,7 +263,7 @@ public class EntityPacketRewriter1_14 extends LegacyEntityRewriter<ClientboundPa
map(Types.DOUBLE); // Needs to be mapped for the position cache
map(Types.DOUBLE);
map(Types.DOUBLE);
handler(wrapper -> addTrackedEntity(wrapper, wrapper.get(Types.VAR_INT, 0), EntityTypes1_14.LIGHTNING_BOLT));
handler(wrapper -> trackAndCacheEntityPosition(wrapper, EntityTypes1_14.LIGHTNING_BOLT));
}
});
@@ -278,7 +277,7 @@ public class EntityPacketRewriter1_14 extends LegacyEntityRewriter<ClientboundPa
map(Types.BYTE);
// Track entity
handler(wrapper -> addTrackedEntity(wrapper, wrapper.get(Types.VAR_INT, 0), EntityTypes1_14.PAINTING));
handler(wrapper -> trackAndCacheEntityPosition(wrapper, EntityTypes1_14.PAINTING));
}
});
@@ -319,11 +318,10 @@ public class EntityPacketRewriter1_14 extends LegacyEntityRewriter<ClientboundPa
wrapper.passthrough(Types.STRING); // Level Type
wrapper.read(Types.VAR_INT); // Read View Distance
//TODO Track client position
// Manually add position storage
/*int entitiyId = wrapper.get(Type.INT, 0);
StoredEntityData storedEntity = protocol.getEntityRewriter().tracker(wrapper.user()).entityData(entitiyId);
storedEntity.put(new EntityPositionStorage1_14());*/
final int entityId = wrapper.get(Types.INT, 0);
final StoredEntityData storedEntity = tracker(wrapper.user()).entityData(entityId);
storedEntity.put(new EntityPositionStorage1_14());
});
}
});
@@ -338,8 +336,10 @@ public class EntityPacketRewriter1_14 extends LegacyEntityRewriter<ClientboundPa
int dimensionId = wrapper.get(Types.INT, 0);
if (clientWorld.setEnvironment(dimensionId)) {
tracker(wrapper.user()).clearEntities();
EntityTracker tracker = tracker(wrapper.user());
tracker.clearEntities();
wrapper.user().get(ChunkLightStorage.class).clear();
tracker.entityData(tracker.clientEntityId()).put(new EntityPositionStorage1_14());
}
short difficulty = wrapper.user().get(DifficultyStorage.class).getDifficulty();
@@ -347,6 +347,27 @@ public class EntityPacketRewriter1_14 extends LegacyEntityRewriter<ClientboundPa
});
}
});
PacketHandler absoluteMoveHandler = wrapper -> {
final double x = wrapper.passthrough(Types.DOUBLE);
final double y = wrapper.passthrough(Types.DOUBLE);
final double z = wrapper.passthrough(Types.DOUBLE);
positionHandler.cacheEntityPosition(wrapper, tracker(wrapper.user()).clientEntityId(), x, y, z, false, false);
};
protocol.registerServerbound(ServerboundPackets1_13.MOVE_PLAYER_POS, absoluteMoveHandler);
protocol.registerServerbound(ServerboundPackets1_13.MOVE_PLAYER_POS_ROT, absoluteMoveHandler);
}
private void trackAndCacheEntityPosition(PacketWrapper wrapper, EntityType type) {
// Tracks the entity + cache the position for the entity
tracker(wrapper.user()).addEntity(wrapper.get(Types.VAR_INT, 0), type);
if (type == EntityTypes1_14.PAINTING) {
final BlockPosition position = wrapper.get(Types.BLOCK_POSITION1_8, 0);
positionHandler.cacheEntityPosition(wrapper, position.x(), position.y(), position.z(), true, false);
} else {
positionHandler.cacheEntityPosition(wrapper, true, false);
}
}
@Override
@@ -25,6 +25,7 @@ import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.rewriter.BlockItemPa
import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.rewriter.CommandRewriter1_16_2;
import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.rewriter.EntityPacketRewriter1_16_2;
import com.viaversion.viabackwards.protocol.v1_16_2to1_16_1.storage.BiomeStorage;
import com.viaversion.viabackwards.utils.BackwardsProtocolLogger;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.RegistryType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_16_2;
@@ -46,7 +47,7 @@ import com.viaversion.viaversion.util.ProtocolLogger;
public class Protocol1_16_2To1_16_1 extends BackwardsProtocol<ClientboundPackets1_16_2, ClientboundPackets1_16, ServerboundPackets1_16_2, ServerboundPackets1_16> {
public static final BackwardsMappingData MAPPINGS = new BackwardsMappingData("1.16.2", "1.16", Protocol1_16_1To1_16_2.class);
public static final ProtocolLogger LOGGER = new ProtocolLogger(Protocol1_16_2To1_16_1.class);
public static final ProtocolLogger LOGGER = new BackwardsProtocolLogger(Protocol1_16_2To1_16_1.class);
private final EntityPacketRewriter1_16_2 entityRewriter = new EntityPacketRewriter1_16_2(this);
private final BlockItemPacketRewriter1_16_2 blockItemPackets = new BlockItemPacketRewriter1_16_2(this);
private final ParticleRewriter<ClientboundPackets1_16_2> particleRewriter = new ParticleRewriter<>(this);
@@ -262,7 +262,7 @@ public class BlockItemPacketRewriter1_16 extends BackwardsItemRewriter<Clientbou
public Item handleItemToClient(UserConnection connection, Item item) {
if (item == null) return null;
super.handleItemToClient(connection, item);
item = super.handleItemToClient(connection, item);
CompoundTag tag = item.tag();
if (item.identifier() == 771 && tag != null) {
@@ -297,7 +297,7 @@ public class BlockItemPacketRewriter1_16 extends BackwardsItemRewriter<Clientbou
if (item == null) return null;
int identifier = item.identifier();
super.handleItemToServer(connection, item);
item = super.handleItemToServer(connection, item);
CompoundTag tag = item.tag();
if (identifier == 771 && tag != null) {
@@ -112,7 +112,7 @@ public final class BlockItemPacketRewriter1_18 extends BackwardsItemRewriter<Cli
int data = wrapper.passthrough(Types.VAR_INT);
wrapper.set(Types.VAR_INT, 0, protocol.getMappingData().getNewBlockStateId(data));
} else if (mappings.isItemParticle(id)) {
handleItemToClient(wrapper.user(), wrapper.passthrough(Types.ITEM1_13_2));
passthroughClientboundItem(wrapper);
}
int newId = protocol.getMappingData().getNewParticleId(id);
@@ -77,11 +77,11 @@ public final class BlockItemPacketRewriter1_19_3 extends BackwardsItemRewriter<C
final int ingredients = wrapper.passthrough(Types.VAR_INT);
for (int j = 0; j < ingredients; j++) {
final Item[] items = wrapper.passthrough(Types.ITEM1_13_2_ARRAY); // Ingredients
for (final Item item : items) {
handleItemToClient(wrapper.user(), item);
for (int k = 0; k < items.length; k++) {
items[k] = handleItemToClient(wrapper.user(), items[k]);
}
}
handleItemToClient(wrapper.user(), wrapper.passthrough(Types.ITEM1_13_2)); // Result
passthroughClientboundItem(wrapper); // Result
}
case "crafting_shaped" -> {
final int ingredients = wrapper.passthrough(Types.VAR_INT) * wrapper.passthrough(Types.VAR_INT);
@@ -89,20 +89,20 @@ public final class BlockItemPacketRewriter1_19_3 extends BackwardsItemRewriter<C
wrapper.read(Types.VAR_INT); // Crafting book category
for (int j = 0; j < ingredients; j++) {
final Item[] items = wrapper.passthrough(Types.ITEM1_13_2_ARRAY); // Ingredients
for (final Item item : items) {
handleItemToClient(wrapper.user(), item);
for (int k = 0; k < items.length; k++) {
items[k] = handleItemToClient(wrapper.user(), items[k]);
}
}
handleItemToClient(wrapper.user(), wrapper.passthrough(Types.ITEM1_13_2)); // Result
passthroughClientboundItem(wrapper); // Result
}
case "smelting", "campfire_cooking", "blasting", "smoking" -> {
wrapper.passthrough(Types.STRING); // Group
wrapper.read(Types.VAR_INT); // Crafting book category
final Item[] items = wrapper.passthrough(Types.ITEM1_13_2_ARRAY); // Ingredients
for (final Item item : items) {
handleItemToClient(wrapper.user(), item);
for (int j = 0; j < items.length; j++) {
items[j] = handleItemToClient(wrapper.user(), items[j]);
}
handleItemToClient(wrapper.user(), wrapper.passthrough(Types.ITEM1_13_2)); // Result
passthroughClientboundItem(wrapper); // Result
wrapper.passthrough(Types.FLOAT); // EXP
wrapper.passthrough(Types.VAR_INT); // Cooking time
}
@@ -77,12 +77,12 @@ public final class BlockItemPacketRewriter1_19 extends BackwardsItemRewriter<Cli
final int size = wrapper.read(Types.VAR_INT);
wrapper.write(Types.UNSIGNED_BYTE, (short) size);
for (int i = 0; i < size; i++) {
handleItemToClient(wrapper.user(), wrapper.passthrough(Types.ITEM1_13_2)); // First item
handleItemToClient(wrapper.user(), wrapper.passthrough(Types.ITEM1_13_2)); // Result
passthroughClientboundItem(wrapper); // First item
passthroughClientboundItem(wrapper); // Result
final Item secondItem = wrapper.read(Types.ITEM1_13_2);
Item secondItem = wrapper.read(Types.ITEM1_13_2);
if (secondItem != null) {
handleItemToClient(wrapper.user(), secondItem);
secondItem = handleItemToClient(wrapper.user(), secondItem);
wrapper.write(Types.BOOLEAN, true);
wrapper.write(Types.ITEM1_13_2, secondItem);
} else {
@@ -217,11 +217,11 @@ public final class BlockItemPacketRewriter1_19 extends BackwardsItemRewriter<Cli
}
@Override
public Item handleItemToClient(final UserConnection connection, final Item item) {
public Item handleItemToClient(final UserConnection connection, Item item) {
if (item == null) return null;
final int identifier = item.identifier();
super.handleItemToClient(connection, item);
item = super.handleItemToClient(connection, item);
if (identifier != 834) {
return item;
@@ -246,10 +246,10 @@ public final class BlockItemPacketRewriter1_19 extends BackwardsItemRewriter<Cli
}
@Override
public Item handleItemToServer(final UserConnection connection, final Item item) {
public Item handleItemToServer(final UserConnection connection, Item item) {
if (item == null) return null;
super.handleItemToServer(connection, item);
item = super.handleItemToServer(connection, item);
CompoundTag tag = item.tag();
if (item.identifier() == 834 && tag != null) {
@@ -161,7 +161,7 @@ public final class BlockItemPacketRewriter1_20_2 extends BackwardsItemRewriter<C
if (wrapper.passthrough(Types.BOOLEAN)) {
wrapper.passthrough(Types.COMPONENT); // Title
wrapper.passthrough(Types.COMPONENT); // Description
wrapper.write(Types.ITEM1_13_2, handleItemToClient(wrapper.user(), wrapper.read(Types.ITEM1_20_2))); // Icon
passthroughClientboundItem(wrapper); // Icon
wrapper.passthrough(Types.VAR_INT); // Frame type
final int flags = wrapper.passthrough(Types.INT); // Flags
if ((flags & 1) != 0) {
@@ -29,6 +29,7 @@ import com.viaversion.viabackwards.protocol.v1_20_3to1_20_2.storage.SpawnPositio
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_3;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
@@ -151,7 +152,8 @@ public final class Protocol1_20_3To1_20_2 extends BackwardsProtocol<ClientboundP
if (wrapper.passthrough(Types.BOOLEAN)) {
convertComponent(wrapper); // Title
convertComponent(wrapper); // Description
itemRewriter.handleItemToClient(wrapper.user(), wrapper.passthrough(Types.ITEM1_20_2)); // Icon
final Item icon = itemRewriter.handleItemToClient(wrapper.user(), wrapper.read(Types.ITEM1_20_2));
wrapper.write(Types.ITEM1_20_2, icon);
wrapper.passthrough(Types.VAR_INT); // Frame type
final int flags = wrapper.passthrough(Types.INT);
if ((flags & 1) != 0) {
@@ -348,7 +348,7 @@ public final class BlockItemPacketRewriter1_20_5 extends BackwardsStructuredItem
}
@Override
public @Nullable Item handleItemToClient(final UserConnection connection, final Item item) {
public @Nullable Item handleItemToClient(final UserConnection connection, Item item) {
if (item.isEmpty()) {
// Back to null for the older protocols
return null;
@@ -358,7 +358,7 @@ public final class BlockItemPacketRewriter1_20_5 extends BackwardsStructuredItem
item.dataContainer().setIdLookup(protocol, true);
enchantmentRewriter.handleToClient(item);
super.handleItemToClient(connection, item);
item = super.handleItemToClient(connection, item);
// Text components since we skip the usual rewrite method
updateTextComponent(connection, item, StructuredDataKey.ITEM_NAME, "item_name");
@@ -112,7 +112,7 @@ public final class BlockItemPacketRewriter1_20 extends BackwardsItemRewriter<Cli
if (wrapper.passthrough(Types.BOOLEAN)) {
wrapper.passthrough(Types.COMPONENT); // Title
wrapper.passthrough(Types.COMPONENT); // Description
handleItemToClient(wrapper.user(), wrapper.passthrough(Types.ITEM1_13_2)); // Icon
passthroughClientboundItem(wrapper); // Icon
wrapper.passthrough(Types.VAR_INT); // Frame type
int flags = wrapper.passthrough(Types.INT); // Flags
if ((flags & 1) != 0) {
@@ -153,12 +153,12 @@ public final class BlockItemPacketRewriter1_20 extends BackwardsItemRewriter<Cli
}
@Override
public @Nullable Item handleItemToClient(UserConnection connection, @Nullable final Item item) {
public @Nullable Item handleItemToClient(UserConnection connection, @Nullable Item item) {
if (item == null) {
return null;
}
super.handleItemToClient(connection, item);
item = super.handleItemToClient(connection, item);
// Remove new trim tags
final CompoundTag trimTag;
@@ -177,12 +177,12 @@ public final class BlockItemPacketRewriter1_20 extends BackwardsItemRewriter<Cli
}
@Override
public @Nullable Item handleItemToServer(UserConnection connection, @Nullable final Item item) {
public @Nullable Item handleItemToServer(UserConnection connection, @Nullable Item item) {
if (item == null) {
return null;
}
super.handleItemToServer(connection, item);
item = super.handleItemToServer(connection, item);
// Add back original trim tag
final Tag trimTag;
@@ -42,6 +42,7 @@ import com.viaversion.viaversion.api.minecraft.item.data.Enchantments;
import com.viaversion.viaversion.api.minecraft.item.data.Equippable;
import com.viaversion.viaversion.api.minecraft.item.data.FoodProperties1_20_5;
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.UseCooldown;
@@ -296,16 +297,16 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem
}
@Override
public Item handleItemToClient(final UserConnection connection, final Item item) {
public Item handleItemToClient(final UserConnection connection, Item item) {
backupInconvertibleData(item);
super.handleItemToClient(connection, item);
item = super.handleItemToClient(connection, item);
downgradeItemData(item);
return item;
}
@Override
public Item handleItemToServer(final UserConnection connection, final Item item) {
super.handleItemToServer(connection, item);
public Item handleItemToServer(final UserConnection connection, Item item) {
item = super.handleItemToServer(connection, item);
// Handle food properties item manually here - the only protocol that has it
// The other way around it's handled by the super handleItemToClient method
@@ -367,9 +368,9 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem
backupTag.put("use_cooldown", tag);
}
final Key itemModel = data.get(StructuredDataKey.ITEM_MODEL);
final ItemModel itemModel = data.get(StructuredDataKey.ITEM_MODEL);
if (itemModel != null) {
backupTag.putString("item_model", itemModel.original());
backupTag.putString("item_model", itemModel.key().original());
}
final Equippable equippable = data.get(StructuredDataKey.EQUIPPABLE1_21_2);
@@ -539,7 +540,7 @@ public final class BlockItemPacketRewriter1_21_2 extends BackwardsStructuredItem
final String itemModel = backupTag.getString("item_model");
if (itemModel != null) {
data.set(StructuredDataKey.ITEM_MODEL, Key.of(itemModel));
data.set(StructuredDataKey.ITEM_MODEL, new ItemModel(Key.of(itemModel)));
}
final CompoundTag equippable = backupTag.getCompoundTag("equippable");
@@ -23,6 +23,7 @@ import com.viaversion.nbt.tag.IntTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viabackwards.ViaBackwards;
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;
@@ -102,7 +103,7 @@ public final class EntityPacketRewriter1_21_2 extends EntityRewriter<Clientbound
}
});
final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter(protocol);
final RegistryDataRewriter registryDataRewriter = new BackwardsRegistryRewriter(protocol);
registryDataRewriter.addEnchantmentEffectRewriter("change_item_damage", tag -> tag.putString("type", "damage_item"));
protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, wrapper -> {
final String registryKey = Key.stripMinecraftNamespace(wrapper.passthrough(Types.STRING));
@@ -286,8 +286,7 @@ public final class RecipeStorage implements StorableObject {
yield new Item[]{new StructuredItem(rewriteItemId(id), 1)};
}
case 3 -> {
final Item item = wrapper.read(VersionedTypes.V1_21_2.item());
protocol.getItemRewriter().handleItemToClient(wrapper.user(), item);
final Item item = protocol.getItemRewriter().handleItemToClient(wrapper.user(), wrapper.read(VersionedTypes.V1_21_2.item()));
if (item.isEmpty()) {
protocol.getLogger().warning("Empty item in recipe");
yield new Item[0];
@@ -22,46 +22,45 @@ 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.viaversion.api.connection.ProtocolInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.protocol.ProtocolRunnable;
import com.viaversion.viaversion.connection.StorableObjectTask;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2;
import com.viaversion.viaversion.protocols.v1_21to1_21_2.storage.ClientVehicleStorage;
import io.netty.channel.Channel;
import java.util.logging.Level;
public final class PlayerPacketsTickTask extends ProtocolRunnable {
public final class PlayerPacketsTickTask extends StorableObjectTask<PlayerStorage> {
public PlayerPacketsTickTask() {
super(Protocol1_21_2To1_21.class);
super(PlayerStorage.class);
}
@Override
public void run(final UserConnection connection) {
public void run(final UserConnection connection, final PlayerStorage storableObject) {
final ProtocolInfo protocolInfo = connection.getProtocolInfo();
if (protocolInfo.getClientState() != State.PLAY || protocolInfo.getServerState() != State.PLAY) {
return;
}
final Channel channel = connection.getChannel();
channel.eventLoop().submit(() -> {
if (!channel.isActive() || protocolInfo.getClientState() != State.PLAY || protocolInfo.getServerState() != State.PLAY) {
return;
final EntityTracker entityTracker = connection.getEntityTracker(Protocol1_21_2To1_21.class);
if (!entityTracker.hasClientEntityId()) {
return;
}
try {
if (!connection.has(ClientVehicleStorage.class)) {
storableObject.tick(connection);
}
try {
if (!connection.has(ClientVehicleStorage.class)) {
final PlayerStorage playerStorage = connection.get(PlayerStorage.class);
playerStorage.tick(connection);
}
} catch (final Throwable t) {
ViaBackwards.getPlatform().getLogger().log(Level.SEVERE, "Error while sending player input packet.", t);
}
try {
final PacketWrapper clientTickEndPacket = PacketWrapper.create(ServerboundPackets1_21_2.CLIENT_TICK_END, connection);
clientTickEndPacket.sendToServer(Protocol1_21_2To1_21.class);
} catch (final Throwable t) {
ViaBackwards.getPlatform().getLogger().log(Level.SEVERE, "Error while sending client tick end packet.", t);
}
});
} catch (final Throwable t) {
ViaBackwards.getPlatform().getLogger().log(Level.SEVERE, "Error while sending player input packet.", t);
}
try {
final PacketWrapper clientTickEndPacket = PacketWrapper.create(ServerboundPackets1_21_2.CLIENT_TICK_END, connection);
clientTickEndPacket.sendToServer(Protocol1_21_2To1_21.class);
} catch (final Throwable t) {
ViaBackwards.getPlatform().getLogger().log(Level.SEVERE, "Error while sending client tick end packet.", t);
}
}
}
@@ -84,8 +84,8 @@ public final class BlockItemPacketRewriter1_21_4 extends BackwardsStructuredItem
@Override
public Item handleItemToClient(final UserConnection connection, final Item item) {
super.handleItemToClient(connection, item);
public Item handleItemToClient(final UserConnection connection, Item item) {
item = super.handleItemToClient(connection, item);
final StructuredDataContainer dataContainer = item.dataContainer();
final CustomModelData1_21_4 modelData = dataContainer.get(StructuredDataKey.CUSTOM_MODEL_DATA1_21_4);
@@ -103,8 +103,8 @@ public final class BlockItemPacketRewriter1_21_4 extends BackwardsStructuredItem
}
@Override
public Item handleItemToServer(final UserConnection connection, final Item item) {
super.handleItemToServer(connection, item);
public Item handleItemToServer(final UserConnection connection, Item item) {
item = super.handleItemToServer(connection, item);
final StructuredDataContainer dataContainer = item.dataContainer();
final CompoundTag customData = dataContainer.get(StructuredDataKey.CUSTOM_DATA);
@@ -19,6 +19,7 @@ package com.viaversion.viabackwards.protocol.v1_21_4to1_21_2.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.ListTag;
import com.viaversion.viabackwards.api.rewriters.BackwardsRegistryRewriter;
import com.viaversion.viabackwards.api.rewriters.EntityRewriter;
import com.viaversion.viabackwards.protocol.v1_21_4to1_21_2.Protocol1_21_4To1_21_2;
import com.viaversion.viaversion.api.connection.UserConnection;
@@ -48,7 +49,7 @@ public final class EntityPacketRewriter1_21_4 extends EntityRewriter<Clientbound
registerSetEntityData(ClientboundPackets1_21_2.SET_ENTITY_DATA);
registerRemoveEntities(ClientboundPackets1_21_2.REMOVE_ENTITIES);
final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter(protocol) {
final RegistryDataRewriter registryDataRewriter = new BackwardsRegistryRewriter(protocol) {
@Override
public RegistryEntry[] handle(final UserConnection connection, final String key, final RegistryEntry[] entries) {
final String strippedKey = Key.stripMinecraftNamespace(key);
@@ -78,6 +78,7 @@ 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;
@@ -298,10 +299,19 @@ public final class BlockItemPacketRewriter1_21_5 extends BackwardsStructuredItem
private void handleBlockEntity(final UserConnection connection, final BlockEntity blockEntity) {
final CompoundTag tag = blockEntity.tag();
if (tag != null && (blockEntity.typeId() == SIGN_BOCK_ENTITY_ID || blockEntity.typeId() == HANGING_SIGN_BOCK_ENTITY_ID)) {
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"));
}
final Tag customName = tag.get("CustomName");
if (customName != null) {
tag.putString("CustomName", protocol.getComponentRewriter().toUglyJson(connection, customName));
}
}
private void updateSignMessages(final UserConnection connection, final CompoundTag tag) {
@@ -25,6 +25,7 @@ import com.viaversion.nbt.tag.Tag;
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_4to1_21_5.packet.ClientboundPacket1_21_5;
import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.rewriter.BlockItemPacketRewriter1_21_5;
import com.viaversion.viaversion.util.Key;
@@ -141,6 +142,9 @@ public final class ComponentRewriter1_21_5 extends NBTComponentRewriter<Clientbo
}
}
}
if (hiddenComponents.containsAll(BlockItemPacketRewriter1_21_5.HIDE_ADDITIONAL_KEYS.stream().map(StructuredDataKey::identifier).toList())) {
componentsTag.put("hide_additional_tooltip", new CompoundTag());
}
final ListTag<CompoundTag> attributeModifiers = getNamespacedCompoundTagList(componentsTag, "attribute_modifiers");
if (attributeModifiers != null) {
@@ -250,7 +254,7 @@ public final class ComponentRewriter1_21_5 extends NBTComponentRewriter<Clientbo
}
}
private String toUglyJson(final UserConnection connection, final Tag value) {
String toUglyJson(final UserConnection connection, final Tag value) {
processTag(connection, value);
return SerializerVersion.V1_21_4.toString(SerializerVersion.V1_21_4.toComponent(value));
}
@@ -20,6 +20,7 @@ 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;
@@ -111,7 +112,7 @@ public final class EntityPacketRewriter1_21_5 extends EntityRewriter<Clientbound
}
});
final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter(protocol) {
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");
@@ -25,7 +25,6 @@ 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 com.viaversion.viaversion.util.SerializerVersion;
import java.util.ArrayList;
import java.util.List;
@@ -36,7 +35,7 @@ public class HashedItemConverterStorage implements StorableObject {
public HashedItemConverterStorage(final Protocol<?, ?, ?, ?> protocol) {
final RegistryAccess registryAccess = RegistryAccess.of(this.enchantments, protocol.getMappingData());
final CodecContext context = new CodecRegistryContext(protocol, SerializerVersion.V1_21_5, SerializerVersion.V1_21_5, registryAccess, false);
final CodecContext context = new CodecRegistryContext(protocol, registryAccess, false);
this.hasher = new HashOps(context, HashFunction.CRC32C);
}
@@ -64,7 +64,6 @@ import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.SerializerVersion;
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
@@ -179,14 +178,8 @@ 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, wrapper -> {
final String command = wrapper.passthrough(Types.STRING);
final ClickEvents clickEvents = wrapper.user().get(ClickEvents.class);
if (clickEvents.handleChatCommand(wrapper.user(), command)) {
wrapper.cancel();
}
});
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 -> {
@@ -305,7 +298,7 @@ public final class Protocol1_21_6To1_21_5 extends BackwardsProtocol<ClientboundP
final String url = wrapper.passthrough(Types.STRING);
serverLinks.storeLink(id, url);
} else {
final Tag tag = wrapper.passthrough(Types.COMPOUND_TAG);
final Tag tag = wrapper.passthrough(Types.TAG);
final String url = wrapper.passthrough(Types.STRING);
serverLinks.storeLink(tag, url);
}
@@ -313,10 +306,19 @@ public final class Protocol1_21_6To1_21_5 extends BackwardsProtocol<ClientboundP
wrapper.user().put(serverLinks);
}
private void handleClickEvents(final PacketWrapper wrapper) {
final String command = wrapper.passthrough(Types.STRING);
final ClickEvents clickEvents = wrapper.user().get(ClickEvents.class);
if (clickEvents.handleChatCommand(wrapper.user(), command)) {
wrapper.cancel();
}
}
@Override
public void init(final UserConnection user) {
addEntityTracker(user, new EntityTrackerBase(user, EntityTypes1_21_6.PLAYER));
addItemHasher(user, new ItemHasherBase(this, user, SerializerVersion.V1_21_5, SerializerVersion.V1_21_5));
addItemHasher(user, new ItemHasherBase(this, user));
user.put(new RegistryAndTags());
user.put(new ClickEvents());
}
@@ -21,7 +21,6 @@ import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.FloatTag;
import com.viaversion.nbt.tag.Tag;
import static com.viaversion.viabackwards.utils.ChatUtil.text;
import static com.viaversion.viabackwards.utils.ChatUtil.translate;
public final class NumberRangeInput implements Input {
@@ -109,6 +108,6 @@ public final class NumberRangeInput implements Input {
}
public Tag displayName() {
return translate(labelFormat, label, text(valueAsString()));
return translate(labelFormat, label, translate(valueAsString()));
}
}
@@ -19,6 +19,8 @@ package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.provider;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.nbt.tag.Tag;
import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viabackwards.api.DialogStyleConfig;
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.Protocol1_21_6To1_21_5;
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.Button;
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.data.Dialog;
@@ -52,7 +54,6 @@ import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
import static com.viaversion.viabackwards.utils.ChatUtil.fixStyle;
import static com.viaversion.viabackwards.utils.ChatUtil.text;
import static com.viaversion.viabackwards.utils.ChatUtil.translate;
/**
@@ -105,7 +106,7 @@ public class ChestDialogViewProvider implements DialogViewProvider {
final PacketWrapper openScreen = PacketWrapper.create(ClientboundPackets1_21_5.OPEN_SCREEN, connection);
openScreen.write(Types.VAR_INT, storage.containerId());
openScreen.write(Types.VAR_INT, 2); // Container type id
openScreen.write(Types.TAG, storage.dialog().title());
openScreen.write(Types.TAG, handleTag(connection, storage.dialog().title()));
openScreen.send(Protocol1_21_6To1_21_5.class);
updateDialog(connection, storage.dialog());
}
@@ -119,6 +120,9 @@ public class ChestDialogViewProvider implements DialogViewProvider {
}
final ChestDialogStorage storage = connection.get(ChestDialogStorage.class);
if (storage == null) {
return;
}
final PacketWrapper containerClose = PacketWrapper.create(ClientboundPackets1_21_5.CONTAINER_CLOSE, connection);
containerClose.write(Types.VAR_INT, storage.containerId());
@@ -225,12 +229,14 @@ public class ChestDialogViewProvider implements DialogViewProvider {
}
protected Item createPageNavigationItem() {
final DialogStyleConfig config = ViaBackwards.getConfig().dialogStyleConfig();
return createItem(
"minecraft:arrow",
text("§9§lPage navigation"),
translate(config.pageNavigationTitle()),
"§9Left click: §6Go to next page",
"§9Right click: §6Go to previous page"
config.pageNavigationNext(),
config.pageNavigationPrevious()
);
}
@@ -251,7 +257,7 @@ public class ChestDialogViewProvider implements DialogViewProvider {
final String identifier = itemWidget.item().getString("id");
final int count = itemWidget.item().getInt("count", 1);
final Tag label = text(Key.stripMinecraftNamespace(identifier));
final Tag label = translate(Key.stripMinecraftNamespace(identifier));
final Item item = createItem(identifier, label);
item.setAmount(count);
if (itemWidget.description() != null) {
@@ -282,6 +288,8 @@ public class ChestDialogViewProvider implements DialogViewProvider {
}
protected Item getBooleanInput(final UserConnection connection, final BooleanInput booleanInput) {
final DialogStyleConfig config = ViaBackwards.getConfig().dialogStyleConfig();
final String item = booleanInput.value() ? "minecraft:lime_dye" : "minecraft:gray_dye";
final Tag[] label = ChatUtil.split(booleanInput.label(), "\n");
@@ -290,14 +298,14 @@ public class ChestDialogViewProvider implements DialogViewProvider {
return createItem(
item,
handleTag(connection, booleanInput.label()),
text("§9Left click: §6Toggle value")
translate(config.toggleValue())
);
} else {
final Tag[] lore = new Tag[label.length];
for (int i = 1; i < label.length; i++) {
lore[i - 1] = handleTag(connection, fixStyle(label[i]));
}
lore[lore.length - 1] = text("§9Left click: §6Toggle value");
lore[lore.length - 1] = translate(config.toggleValue());
return createItem(
item,
handleTag(connection, label[0]),
@@ -311,14 +319,16 @@ public class ChestDialogViewProvider implements DialogViewProvider {
}
protected Item getNumberRangeInput(final UserConnection connection, final NumberRangeInput numberRangeInput) {
final DialogStyleConfig config = ViaBackwards.getConfig().dialogStyleConfig();
final Tag label = handleTag(connection, numberRangeInput.displayName());
return createItem(
"minecraft:clock",
label,
"§9Left click: §6Increase value by " + numberRangeInput.step(),
"§9Right click: §6Decrease value by " + numberRangeInput.step(),
"§7(Value between §a" + numberRangeInput.start() + " §7and §a" + numberRangeInput.end() + "§7)"
String.format(config.increaseValue(), numberRangeInput.step()),
String.format(config.decreaseValue(), numberRangeInput.step()),
String.format(config.valueRange(), numberRangeInput.start(), numberRangeInput.end())
);
}
@@ -333,21 +343,25 @@ public class ChestDialogViewProvider implements DialogViewProvider {
}
protected Item getTextInput(final UserConnection connection, final TextInput textInput) {
final Tag currentValue = text("§7Current value: §a" + textInput.value());
final DialogStyleConfig config = ViaBackwards.getConfig().dialogStyleConfig();
final Tag currentValue = translate(String.format(config.currentValue(), textInput.value()));
if (textInput.label() == null) {
return createItem("minecraft:writable_book", currentValue);
} else {
final Tag label = handleTag(connection, textInput.label());
return createItem("minecraft:writable_book", label, currentValue, text("§9Left click: §6Edit text"));
return createItem("minecraft:writable_book", label, currentValue, translate(config.editValue()));
}
}
protected void clickTextInput(final UserConnection connection, final TextInput textInput) {
final ChestDialogStorage storage = connection.get(ChestDialogStorage.class);
openAnvilView(connection, storage, text("§7Edit text"), textInput.value(), textInput);
openAnvilView(connection, storage, translate("§7Edit text"), textInput.value(), textInput);
}
protected Item getSingleOptionInput(final UserConnection connection, final SingleOptionInput singleOptionInput) {
final DialogStyleConfig config = ViaBackwards.getConfig().dialogStyleConfig();
final Tag displayName = singleOptionInput.options()[singleOptionInput.value()].computeDisplay();
final Tag label;
if (singleOptionInput.label() != null) {
@@ -358,8 +372,8 @@ public class ChestDialogViewProvider implements DialogViewProvider {
return createItem(
"minecraft:bookshelf",
handleTag(connection, label),
"§9Left click: §6Go to next option",
"§9Right click: §6Go to previous option"
config.nextOption(),
config.previousOption()
);
}
@@ -388,7 +402,7 @@ public class ChestDialogViewProvider implements DialogViewProvider {
case "open_url" -> {
// We can't open a URL for the client, so roughly emulate by opening an Anvil containing the URL.
final String url = clickEvent.getString("url");
openAnvilView(connection, storage, text("Open URL"), url, null);
openAnvilView(connection, storage, translate("Open URL"), url, null);
}
case "run_command" -> {
// The vanilla client validates for signed argument types and has more requirements for this click event,
@@ -404,7 +418,7 @@ public class ChestDialogViewProvider implements DialogViewProvider {
case "copy_to_clipboard" -> {
// Same as above, we can't access the clipboard
final String value = clickEvent.getString("value");
openAnvilView(connection, storage, text("Copy to clipboard"), value, null);
openAnvilView(connection, storage, translate("Copy to clipboard"), value, null);
}
}
@@ -412,14 +426,16 @@ public class ChestDialogViewProvider implements DialogViewProvider {
}
protected Item createTextInputItem(final String value) {
return createItem("minecraft:paper", text(value), "§9Left click/close: §6Set text");
final DialogStyleConfig config = ViaBackwards.getConfig().dialogStyleConfig();
return createItem("minecraft:paper", translate(value), config.setText());
}
protected Item createTextCopyItem(final String value) {
return createItem("minecraft:paper", text(value), "§9Left click: §6Close");
final DialogStyleConfig config = ViaBackwards.getConfig().dialogStyleConfig();
return createItem("minecraft:paper", translate(value), config.close());
}
private void openAnvilView(
protected void openAnvilView(
final UserConnection connection,
final ChestDialogStorage storage,
final Tag title,
@@ -545,7 +561,7 @@ public class ChestDialogViewProvider implements DialogViewProvider {
* @param tag the text component as a tag, or null if no tag is present
* @return the rewritten tag, or null if the input tag was null
*/
private @Nullable Tag handleTag(final UserConnection connection, final @Nullable Tag tag) {
protected @Nullable Tag handleTag(final UserConnection connection, final @Nullable Tag tag) {
if (tag == null) {
return null;
}
@@ -589,7 +605,7 @@ public class ChestDialogViewProvider implements DialogViewProvider {
if (description.length > 0) {
final List<Tag> lore = new ArrayList<>();
for (final String s : description) {
lore.add(text(s));
lore.add(translate(s));
}
data.set(StructuredDataKey.LORE, lore.toArray(new Tag[0]));
}
@@ -20,7 +20,6 @@ package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.rewriters.text.NBTComponentRewriter;
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ChestDialogStorage;
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ClickEvents;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPacket1_21_6;
@@ -42,15 +41,6 @@ public final class ComponentRewriter1_21_6 extends NBTComponentRewriter<Clientbo
final String action = clickEvent.getString("action");
final ChestDialogStorage chestDialogStorage = connection.get(ChestDialogStorage.class);
if (chestDialogStorage != null) {
// Short way out - remove when in dialog, buttons are handled separately
if ("show_dialog".equals(action) || "custom".equals(action)) {
tag.remove("click_event");
return;
}
}
// Make them run a command generated by us executing the actual logic
if ("show_dialog".equals(action)) {
final ClickEvents clickEvents = connection.get(ClickEvents.class);
@@ -31,7 +31,6 @@ import com.viaversion.viaversion.protocols.v1_21_4to1_21_5.packet.ClientboundPac
import java.util.concurrent.atomic.AtomicInteger;
import org.checkerframework.checker.nullness.qual.Nullable;
import static com.viaversion.viabackwards.utils.ChatUtil.text;
import static com.viaversion.viabackwards.utils.ChatUtil.translate;
/**
@@ -44,7 +43,7 @@ public final class ChestDialogStorage implements StorableObject {
private static final AtomicInteger FAKE_ID_COUNTER = new AtomicInteger(MIN_FAKE_ID);
private static final Tag[] RESPONSE_BUTTON_LABELS = new Tag[]{
text(""),
translate(""),
translate("gui.waitingForResponse.button.inactive", 4),
translate("gui.waitingForResponse.button.inactive", 3),
translate("gui.waitingForResponse.button.inactive", 2),
@@ -17,22 +17,18 @@
*/
package com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.task;
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.Protocol1_21_6To1_21_5;
import com.viaversion.viabackwards.protocol.v1_21_6to1_21_5.storage.ChestDialogStorage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocol.ProtocolRunnable;
import com.viaversion.viaversion.connection.StorableObjectTask;
public final class ChestDialogViewTask extends ProtocolRunnable {
public final class ChestDialogViewTask extends StorableObjectTask<ChestDialogStorage> {
public ChestDialogViewTask() {
super(Protocol1_21_6To1_21_5.class);
super(ChestDialogStorage.class);
}
@Override
public void run(final UserConnection connection) {
final ChestDialogStorage storage = connection.get(ChestDialogStorage.class);
if (storage != null) {
storage.tick(connection);
}
public void run(final UserConnection userConnection, final ChestDialogStorage storableObject) {
storableObject.tick(userConnection);
}
}
@@ -44,7 +44,6 @@ import com.viaversion.viaversion.protocols.v1_21_6to1_21_7.Protocol1_21_6To1_21_
import com.viaversion.viaversion.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import com.viaversion.viaversion.util.SerializerVersion;
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
@@ -95,7 +94,7 @@ public final class Protocol1_21_7To1_21_6 extends BackwardsProtocol<ClientboundP
@Override
public void init(final UserConnection connection) {
addEntityTracker(connection, new EntityTrackerBase(connection, EntityTypes1_21_6.PLAYER));
addItemHasher(connection, new ItemHasherBase(this, connection, SerializerVersion.V1_21_6, SerializerVersion.V1_21_6));
addItemHasher(connection, new ItemHasherBase(this, connection));
}
@Override
@@ -0,0 +1,252 @@
/*
* 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;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viabackwards.api.BackwardsProtocol;
import com.viaversion.viabackwards.api.data.BackwardsMappingData;
import com.viaversion.viabackwards.api.rewriters.SoundRewriter;
import com.viaversion.viabackwards.api.rewriters.text.NBTComponentRewriter;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.rewriter.BlockItemPacketRewriter1_21_9;
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.storage.PlayerRotationStorage;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.tracker.EntityTracker1_21_9;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.data.version.StructuredDataKeys1_21_5;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_9;
import com.viaversion.viaversion.api.minecraft.entitydata.types.EntityDataTypes1_21_5;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.provider.PacketTypesProvider;
import com.viaversion.viaversion.api.protocol.packet.provider.SimplePacketTypesProvider;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.types.version.Types1_20_5;
import com.viaversion.viaversion.api.type.types.version.VersionedTypes;
import com.viaversion.viaversion.api.type.types.version.VersionedTypesHolder;
import com.viaversion.viaversion.data.item.ItemHasherBase;
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundConfigurationPackets1_21_6;
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPacket1_21_6;
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPackets1_21_6;
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundConfigurationPackets1_21_6;
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPacket1_21_6;
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ServerboundPackets1_21_6;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.Protocol1_21_7To1_21_9;
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.rewriter.ParticleRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import static com.viaversion.viaversion.util.ProtocolUtil.packetTypeMap;
public final class Protocol1_21_9To1_21_7 extends BackwardsProtocol<ClientboundPacket1_21_9, ClientboundPacket1_21_6, ServerboundPacket1_21_9, ServerboundPacket1_21_6> {
public static final BackwardsMappingData MAPPINGS = new BackwardsMappingData("1.21.9", "1.21.7", Protocol1_21_7To1_21_9.class);
private final EntityPacketRewriter1_21_9 entityRewriter = new EntityPacketRewriter1_21_9(this);
private final BlockItemPacketRewriter1_21_9 itemRewriter = new BlockItemPacketRewriter1_21_9(this);
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);
public Protocol1_21_9To1_21_7() {
super(ClientboundPacket1_21_9.class, ClientboundPacket1_21_6.class, ServerboundPacket1_21_9.class, ServerboundPacket1_21_6.class);
}
@Override
protected void registerPackets() {
super.registerPackets();
tagRewriter.registerGeneric(ClientboundPackets1_21_9.UPDATE_TAGS);
tagRewriter.registerGeneric(ClientboundConfigurationPackets1_21_9.UPDATE_TAGS);
final SoundRewriter<ClientboundPacket1_21_9> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound1_19_3(ClientboundPackets1_21_9.SOUND);
soundRewriter.registerSound1_19_3(ClientboundPackets1_21_9.SOUND_ENTITY);
soundRewriter.registerStopSound(ClientboundPackets1_21_9.STOP_SOUND);
new StatisticsRewriter<>(this).register(ClientboundPackets1_21_9.AWARD_STATS);
translatableRewriter.registerOpenScreen1_14(ClientboundPackets1_21_9.OPEN_SCREEN);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_9.SET_ACTION_BAR_TEXT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_9.SET_TITLE_TEXT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_9.SET_SUBTITLE_TEXT);
translatableRewriter.registerBossEvent(ClientboundPackets1_21_9.BOSS_EVENT);
translatableRewriter.registerComponentPacket(ClientboundPackets1_21_9.DISCONNECT);
translatableRewriter.registerTabList(ClientboundPackets1_21_9.TAB_LIST);
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);
translatableRewriter.registerDisguisedChat(ClientboundPackets1_21_9.DISGUISED_CHAT);
translatableRewriter.registerPlayerChat1_21_5(ClientboundPackets1_21_9.PLAYER_CHAT);
translatableRewriter.registerPing();
particleRewriter.registerLevelParticles1_21_4(ClientboundPackets1_21_9.LEVEL_PARTICLES);
registerClientbound(ClientboundPackets1_21_9.EXPLODE, wrapper -> {
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
wrapper.read(Types.FLOAT); // Radius
wrapper.read(Types.INT); // Affected blocks
if (wrapper.passthrough(Types.BOOLEAN)) {
wrapper.passthrough(Types.DOUBLE); // Knockback X
wrapper.passthrough(Types.DOUBLE); // Knockback Y
wrapper.passthrough(Types.DOUBLE); // Knockback Z
}
particleRewriter.passthroughParticle(wrapper); // Explosion particle
soundRewriter.soundHolderHandler().handle(wrapper);
final int blockParticles = wrapper.read(Types.VAR_INT);
for (int i = 0; i < blockParticles; i++) {
wrapper.read(particleRewriter.particleType());
wrapper.read(Types.FLOAT); // Scaling
wrapper.read(Types.FLOAT); // Speed
wrapper.read(Types.VAR_INT); // Weight
}
});
registerClientbound(ClientboundConfigurationPackets1_21_9.CODE_OF_CONDUCT, ClientboundConfigurationPackets1_21_6.SHOW_DIALOG, wrapper -> {
if (wrapper.user().getProtocolInfo().protocolVersion().olderThanOrEqualTo(ProtocolVersion.v1_21_5)) {
// TODO Remove once we implement dialogs during the configuration state in 1.21.6->1.21.5
wrapper.cancel();
final PacketWrapper acceptPacket = wrapper.create(ServerboundConfigurationPackets1_21_9.ACCEPT_CODE_OF_CONDUCT);
acceptPacket.sendToServer(Protocol1_21_9To1_21_7.class);
return;
}
final String codeOfConduct = wrapper.read(Types.STRING);
final CompoundTag tag = new CompoundTag();
tag.putString("type", "minecraft:confirmation");
tag.putString("title", translatableRewriter.mappedTranslationKey("multiplayer.codeOfConduct.title"));
final CompoundTag body = new CompoundTag();
body.putString("type", "minecraft:plain_message");
body.putString("contents", codeOfConduct);
tag.put("body", body);
final CompoundTag yes = new CompoundTag();
final CompoundTag yesLabel = new CompoundTag();
yesLabel.putString("translate", "gui.acknowledge");
yes.put("label", yesLabel);
final CompoundTag acceptAction = new CompoundTag();
acceptAction.putString("type", "minecraft:custom");
acceptAction.putString("id", "viabackwards:ack_code_of_conduct");
yes.put("action", acceptAction);
tag.put("yes", yes);
final CompoundTag no = new CompoundTag();
final CompoundTag noLabel = new CompoundTag();
noLabel.putString("translate", "menu.disconnect");
no.put("label", noLabel);
final CompoundTag disconnectAction = new CompoundTag();
disconnectAction.putString("type", "minecraft:custom");
disconnectAction.putString("id", "viabackwards:disconnect");
no.put("action", disconnectAction);
tag.put("no", no);
wrapper.write(Types.TAG, tag);
});
registerServerbound(ServerboundConfigurationPackets1_21_6.CUSTOM_CLICK_ACTION, wrapper -> {
final String id = wrapper.passthrough(Types.STRING);
if ("viabackwards:ack_code_of_conduct".equals(id)) {
wrapper.cancel();
final PacketWrapper acceptPacket = wrapper.create(ServerboundConfigurationPackets1_21_9.ACCEPT_CODE_OF_CONDUCT);
acceptPacket.sendToServer(Protocol1_21_9To1_21_7.class);
} else if ("viabackwards:disconnect".equals(id)) {
wrapper.cancel();
wrapper.user().disconnect(translatableRewriter.mappedTranslationKey("multiplayer.disconnect.code_of_conduct"));
}
});
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
public void init(final UserConnection connection) {
addEntityTracker(connection, new EntityTracker1_21_9(connection, EntityTypes1_21_9.PLAYER));
addItemHasher(connection, new ItemHasherBase(this, connection));
connection.put(new PlayerRotationStorage());
}
@Override
public BackwardsMappingData getMappingData() {
return MAPPINGS;
}
@Override
public EntityPacketRewriter1_21_9 getEntityRewriter() {
return entityRewriter;
}
@Override
public BlockItemPacketRewriter1_21_9 getItemRewriter() {
return itemRewriter;
}
@Override
public ParticleRewriter<ClientboundPacket1_21_9> getParticleRewriter() {
return particleRewriter;
}
@Override
public NBTComponentRewriter<ClientboundPacket1_21_9> getComponentRewriter() {
return translatableRewriter;
}
@Override
public TagRewriter<ClientboundPacket1_21_9> getTagRewriter() {
return tagRewriter;
}
@Override
public VersionedTypesHolder types() {
return VersionedTypes.V1_21_9;
}
@Override
public Types1_20_5<StructuredDataKeys1_21_5, EntityDataTypes1_21_5> mappedTypes() {
return VersionedTypes.V1_21_6;
}
@Override
protected PacketTypesProvider<ClientboundPacket1_21_9, ClientboundPacket1_21_6, ServerboundPacket1_21_9, ServerboundPacket1_21_6> createPacketTypesProvider() {
return new SimplePacketTypesProvider<>(
packetTypeMap(unmappedClientboundPacketType, ClientboundPackets1_21_9.class, ClientboundConfigurationPackets1_21_9.class),
packetTypeMap(mappedClientboundPacketType, ClientboundPackets1_21_6.class, ClientboundConfigurationPackets1_21_6.class),
packetTypeMap(mappedServerboundPacketType, ServerboundPackets1_21_6.class, ServerboundConfigurationPackets1_21_9.class),
packetTypeMap(unmappedServerboundPacketType, ServerboundPackets1_21_6.class, ServerboundConfigurationPackets1_21_6.class)
);
}
}
@@ -0,0 +1,126 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
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.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.ResolvableProfile;
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.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;
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.ClientboundPacket1_21_9;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundPackets1_21_9;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.RecipeDisplayRewriter;
import static com.viaversion.viaversion.protocols.v1_21_7to1_21_9.rewriter.BlockItemPacketRewriter1_21_9.downgradeData;
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> {
public BlockItemPacketRewriter1_21_9(final Protocol1_21_9To1_21_7 protocol) {
super(protocol);
}
@Override
public void registerPackets() {
final BlockRewriter<ClientboundPacket1_21_9> blockRewriter = BlockRewriter.for1_20_2(protocol);
blockRewriter.registerBlockEvent(ClientboundPackets1_21_9.BLOCK_EVENT);
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);
registerSetCursorItem(ClientboundPackets1_21_9.SET_CURSOR_ITEM);
registerSetPlayerInventory(ClientboundPackets1_21_9.SET_PLAYER_INVENTORY);
registerCooldown1_21_2(ClientboundPackets1_21_9.COOLDOWN);
registerSetContent1_21_2(ClientboundPackets1_21_9.CONTAINER_SET_CONTENT);
registerSetSlot1_21_2(ClientboundPackets1_21_9.CONTAINER_SET_SLOT);
registerAdvancements1_20_3(ClientboundPackets1_21_9.UPDATE_ADVANCEMENTS);
registerSetEquipment(ClientboundPackets1_21_9.SET_EQUIPMENT);
registerMerchantOffers1_20_5(ClientboundPackets1_21_9.MERCHANT_OFFERS);
registerContainerClick1_21_5(ServerboundPackets1_21_6.CONTAINER_CLICK);
registerSetCreativeModeSlot1_21_5(ServerboundPackets1_21_6.SET_CREATIVE_MODE_SLOT);
final RecipeDisplayRewriter<ClientboundPacket1_21_9> recipeRewriter = new RecipeDisplayRewriter1_21_5<>(protocol);
recipeRewriter.registerUpdateRecipes(ClientboundPackets1_21_9.UPDATE_RECIPES);
recipeRewriter.registerRecipeBookAdd(ClientboundPackets1_21_9.RECIPE_BOOK_ADD);
recipeRewriter.registerPlaceGhostRecipe(ClientboundPackets1_21_9.PLACE_GHOST_RECIPE);
}
@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 backupInconvertibleData(final UserConnection connection, final Item item, final StructuredDataContainer dataContainer, final CompoundTag backupTag) {
super.backupInconvertibleData(connection, item, dataContainer, backupTag);
final ResolvableProfile profile = dataContainer.get(StructuredDataKey.PROFILE1_21_9);
if (profile != null) {
final CompoundTag profileTag = new CompoundTag();
if (profile.bodyTexture() != null) {
profileTag.putString("body_texture", profile.bodyTexture());
}
if (profile.capeTexture() != null) {
profileTag.putString("cape_texture", profile.capeTexture());
}
if (profile.elytraTexture() != null) {
profileTag.putString("elytra_texture", profile.elytraTexture());
}
if (profile.modelType() != null) {
profileTag.putBoolean("model", profile.modelType() == 0);
}
if (!profileTag.isEmpty()) {
backupTag.put("profile", profileTag);
}
}
}
@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 profileTag = backupTag.getCompoundTag("profile");
if (profileTag != null) {
container.replace(StructuredDataKey.PROFILE1_20_5, StructuredDataKey.PROFILE1_21_9, profile -> new ResolvableProfile(
profile,
profileTag.getString("body_texture"),
profileTag.getString("cape_texture"),
profileTag.getString("elytra_texture"),
profileTag.contains("model") ? (profileTag.getBoolean("model") ? 0 : 1) : null
));
}
}
}
@@ -0,0 +1,42 @@
/*
* 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.text.NBTComponentRewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.data.StructuredDataKey;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundPacket1_21_9;
public final class ComponentRewriter1_21_9 extends NBTComponentRewriter<ClientboundPacket1_21_9> {
public ComponentRewriter1_21_9(final BackwardsProtocol<ClientboundPacket1_21_9, ?, ?, ?> 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.ENTITY_DATA1_21_9, StructuredDataKey.BLOCK_ENTITY_DATA1_21_9);
}
}
@@ -0,0 +1,326 @@
/*
* 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.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;
import com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.storage.PlayerRotationStorage;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockPosition;
import com.viaversion.viaversion.api.minecraft.GameProfile;
import com.viaversion.viaversion.api.minecraft.GlobalBlockPosition;
import com.viaversion.viaversion.api.minecraft.ResolvableProfile;
import com.viaversion.viaversion.api.minecraft.Vector3d;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_6;
import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_21_9;
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.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;
import java.util.UUID;
import java.util.concurrent.ThreadLocalRandom;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class EntityPacketRewriter1_21_9 extends EntityRewriter<ClientboundPacket1_21_9, Protocol1_21_9To1_21_7> {
public EntityPacketRewriter1_21_9(final Protocol1_21_9To1_21_7 protocol) {
super(protocol, VersionedTypes.V1_21_9.entityDataTypes.optionalComponentType, VersionedTypes.V1_21_9.entityDataTypes.booleanType);
}
@Override
public void registerPackets() {
registerSetEntityData(ClientboundPackets1_21_9.SET_ENTITY_DATA);
registerRemoveEntities(ClientboundPackets1_21_9.REMOVE_ENTITIES);
registerPlayerAbilities(ClientboundPackets1_21_9.PLAYER_ABILITIES);
registerGameEvent(ClientboundPackets1_21_9.GAME_EVENT);
registerLogin1_20_5(ClientboundPackets1_21_9.LOGIN);
registerRespawn1_20_5(ClientboundPackets1_21_9.RESPAWN);
protocol.registerClientbound(ClientboundPackets1_21_9.ADD_ENTITY, wrapper -> {
final int entityId = wrapper.passthrough(Types.VAR_INT);
final UUID uuid = wrapper.passthrough(Types.UUID);
final int entityTypeId = wrapper.passthrough(Types.VAR_INT);
wrapper.passthrough(Types.DOUBLE); // X
wrapper.passthrough(Types.DOUBLE); // Y
wrapper.passthrough(Types.DOUBLE); // Z
final Vector3d movement = wrapper.read(Types.MOVEMENT_VECTOR);
wrapper.passthrough(Types.BYTE); // Pitch
wrapper.passthrough(Types.BYTE); // Yaw
wrapper.passthrough(Types.BYTE); // Head yaw
final int data = wrapper.passthrough(Types.VAR_INT);
final EntityType entityType = trackAndRewrite(wrapper, entityTypeId, entityId);
if (protocol.getMappingData() != null && entityType == EntityTypes1_21_9.FALLING_BLOCK) {
final int mappedBlockStateId = protocol.getMappingData().getNewBlockStateId(data);
wrapper.set(Types.VAR_INT, 2, mappedBlockStateId);
}
writeMovementShorts(wrapper, movement);
if (EntityTypes1_21_9.getTypeFromId(entityTypeId) == EntityTypes1_21_9.MANNEQUIN) {
final String name = randomHackyEmptyName();
final MannequinData mannequinData = new MannequinData(uuid, name);
tracker(wrapper.user()).entity(entityId).data().put(mannequinData);
sendInitialPlayerInfoUpdate(wrapper, mannequinData);
}
});
protocol.registerClientbound(ClientboundPackets1_21_9.SET_ENTITY_MOTION, wrapper -> {
wrapper.passthrough(Types.VAR_INT); // Entity ID
writeMovementShorts(wrapper, wrapper.read(Types.MOVEMENT_VECTOR));
});
protocol.registerClientbound(ClientboundPackets1_21_9.PLAYER_ROTATION, wrapper -> {
final PlayerRotationStorage storage = wrapper.user().get(PlayerRotationStorage.class);
float yRot = wrapper.read(Types.FLOAT);
if (wrapper.read(Types.BOOLEAN)) {
yRot = storage.yaw() + yRot;
}
float xRot = wrapper.read(Types.FLOAT);
if (wrapper.read(Types.BOOLEAN)) {
xRot = storage.pitch() + xRot;
}
wrapper.write(Types.FLOAT, yRot);
wrapper.write(Types.FLOAT, xRot);
storage.setRotation(yRot, xRot); // Update after having used its previous data
});
protocol.registerClientbound(ClientboundPackets1_21_9.SET_DEFAULT_SPAWN_POSITION, wrapper -> {
final GlobalBlockPosition pos = wrapper.read(Types.GLOBAL_POSITION);
wrapper.write(Types.BLOCK_POSITION1_14, new BlockPosition(pos.x(), pos.y(), pos.z()));
wrapper.passthrough(Types.FLOAT); // Yaw
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
wrapper.passthrough(Types.DOUBLE); // Z
storePlayerRotation(wrapper);
});
protocol.registerServerbound(ServerboundPackets1_21_6.MOVE_PLAYER_ROT, this::storePlayerRotation);
}
private void sendInitialPlayerInfoUpdate(final PacketWrapper wrapper, final MannequinData mannequinData) {
final PacketWrapper playerInfo = wrapper.create(ClientboundPackets1_21_6.PLAYER_INFO_UPDATE);
final BitSet actions = new BitSet(8);
for (int i = 0; i < 8; i++) {
actions.set(i);
}
playerInfo.write(Types.PROFILE_ACTIONS_ENUM1_21_4, actions);
playerInfo.write(Types.VAR_INT, 1); // One entry
playerInfo.write(Types.UUID, mannequinData.uuid());
playerInfo.write(Types.STRING, mannequinData.name());
playerInfo.write(Types.PROFILE_PROPERTY_ARRAY, new GameProfile.Property[0]);
playerInfo.write(Types.BOOLEAN, false); // Session info
playerInfo.write(Types.VAR_INT, 0); // Gamemode
playerInfo.write(Types.BOOLEAN, false); // Listed
playerInfo.write(Types.VAR_INT, 0); // Latency
playerInfo.write(Types.OPTIONAL_TAG, null);
playerInfo.write(Types.VAR_INT, 1000); // List order
playerInfo.write(Types.BOOLEAN, true); // Show hat
playerInfo.send(Protocol1_21_9To1_21_7.class);
sendPlayerTeamDisplayName(wrapper.user(), mannequinData, null);
}
private void sendPlayerInfoDisplayNameUpdate(final UserConnection connection, final MannequinData mannequinData, @Nullable final Tag displayName) {
final PacketWrapper playerInfo = PacketWrapper.create(ClientboundPackets1_21_6.PLAYER_INFO_UPDATE, connection);
final BitSet actions = new BitSet(8);
actions.set(5);
playerInfo.write(Types.PROFILE_ACTIONS_ENUM1_21_4, actions);
playerInfo.write(Types.VAR_INT, 1);
playerInfo.write(Types.UUID, mannequinData.uuid());
playerInfo.write(Types.OPTIONAL_TAG, displayName);
playerInfo.send(Protocol1_21_9To1_21_7.class);
sendPlayerTeamDisplayName(connection, mannequinData, displayName);
}
private void sendPlayerTeamDisplayName(final UserConnection connection, final MannequinData mannequinData, final Tag displayName) {
// Send the display name as a team prefix
final Tag nonNullDisplayName = displayName != null ? displayName : new StringTag("Mannequin");
final PacketWrapper addTeam = PacketWrapper.create(ClientboundPackets1_21_6.SET_PLAYER_TEAM, connection);
addTeam.write(Types.STRING, mannequinData.name());
addTeam.write(Types.BYTE, mannequinData.hasTeam() ? (byte) 2 : 0); // Mode
addTeam.write(Types.TAG, nonNullDisplayName); // Display Name
addTeam.write(Types.BYTE, (byte) 0); // Flags
addTeam.write(Types.VAR_INT, 0); // Nametag visibility
addTeam.write(Types.VAR_INT, 0); // Collision rule
addTeam.write(Types.VAR_INT, 15); // Color
addTeam.write(Types.TAG, nonNullDisplayName); // Prefix
addTeam.write(Types.TAG, new StringTag("")); // Suffix
if (!mannequinData.hasTeam()) {
addTeam.write(Types.STRING_ARRAY, new String[]{mannequinData.name()});
}
addTeam.send(Protocol1_21_9To1_21_7.class);
}
private void sendPlayerInfoProfileUpdate(final UserConnection connection, final UUID uuid, @Nullable final String name, final GameProfile.Property[] properties) {
final PacketWrapper playerInfo = PacketWrapper.create(ClientboundPackets1_21_6.PLAYER_INFO_UPDATE, connection);
final BitSet actions = new BitSet(8);
actions.set(0);
playerInfo.write(Types.PROFILE_ACTIONS_ENUM1_21_4, actions);
playerInfo.write(Types.VAR_INT, 1);
playerInfo.write(Types.UUID, uuid);
playerInfo.write(Types.STRING, name != null ? name : randomHackyEmptyName());
playerInfo.write(Types.PROFILE_PROPERTY_ARRAY, properties);
playerInfo.send(Protocol1_21_9To1_21_7.class);
}
private String randomHackyEmptyName() {
final StringBuilder builder = new StringBuilder();
// Player names cannot be updated after the initial add without fully respawning them;
// Stack random color codes to appear as an empty name, later filled with a team prefix
for (int i = 0; i < 8; i++) {
final int random = ThreadLocalRandom.current().nextInt(ChatColorUtil.ALL_CODES.length());
builder.append('§').append(ChatColorUtil.ALL_CODES.charAt(random));
}
return builder.toString();
}
private void writeMovementShorts(final PacketWrapper wrapper, final Vector3d movement) {
wrapper.write(Types.SHORT, (short) (movement.x() * 8000));
wrapper.write(Types.SHORT, (short) (movement.y() * 8000));
wrapper.write(Types.SHORT, (short) (movement.z() * 8000));
}
private void storePlayerRotation(final PacketWrapper wrapper) {
final float yaw = wrapper.passthrough(Types.FLOAT);
final float pitch = wrapper.passthrough(Types.FLOAT);
wrapper.user().get(PlayerRotationStorage.class).setRotation(yaw, pitch);
}
@Override
protected void registerRewrites() {
final EntityDataTypes1_21_5 entityDataTypes = protocol.mappedTypes().entityDataTypes();
filter().handler((event, data) -> {
int id = data.dataType().typeId();
if (id == VersionedTypes.V1_21_9.entityDataTypes.copperGolemState.typeId()
|| id == VersionedTypes.V1_21_9.entityDataTypes.weatheringCopperState.typeId()) {
event.cancel();
return;
}
if (id == VersionedTypes.V1_21_9.entityDataTypes.mannequinProfileType.typeId()) {
if (event.entityType() == null) {
event.cancel();
}
return; // Handled separately
}
if (id > VersionedTypes.V1_21_9.entityDataTypes.armadilloState.typeId()) {
id -= 2;
}
if (id >= entityDataTypes.compoundTagType.typeId()) {
id++;
}
data.setDataType(entityDataTypes.byId(id));
});
registerEntityDataTypeHandler1_20_3(
entityDataTypes.itemType,
entityDataTypes.blockStateType,
entityDataTypes.optionalBlockStateType,
entityDataTypes.particleType,
entityDataTypes.particlesType,
entityDataTypes.componentType,
entityDataTypes.optionalComponentType
);
final EntityDataHandler shoulderDataHandler = (event, data) -> {
final CompoundTag entityTag = new CompoundTag();
final Integer value = data.value();
if (value != null) {
entityTag.putInt("id", EntityTypes1_21_6.PARROT.getId());
entityTag.putInt("Variant", value);
}
data.setTypeAndValue(protocol.mappedTypes().entityDataTypes.compoundTagType, entityTag);
};
filter().type(EntityTypes1_21_9.PLAYER).index(19).handler(shoulderDataHandler);
filter().type(EntityTypes1_21_9.PLAYER).index(20).handler(shoulderDataHandler);
filter().type(EntityTypes1_21_9.PLAYER).handler((event, data) -> {
if (event.index() == 15) {
event.setIndex(18);
} else if (event.index() == 16) {
event.setIndex(17);
} else if (event.index() == 17 || event.index() == 18) {
event.setIndex(event.index() - 2); // Move hearts and score back down
}
});
filter().type(EntityTypes1_21_9.MANNEQUIN).handler(((event, data) -> {
if (event.index() == 2) { // Display name
final Tag displayName = data.value();
final MannequinData mannequinData = event.trackedEntity().data().get(MannequinData.class);
sendPlayerInfoDisplayNameUpdate(event.user(), mannequinData, displayName);
} else if (event.index() == 17) { // Profile
final ResolvableProfile profile = data.value();
final UUID uuid = event.trackedEntity().data().get(MannequinData.class).uuid();
sendPlayerInfoProfileUpdate(event.user(), uuid, profile.profile().name(), profile.profile().properties());
event.cancel();
} else if (event.index() == 15) {
event.setIndex(18);
} else if (event.index() == 16) {
event.setIndex(17);
} else if (event.index() == 18) {
// TODO Immovable?
event.cancel();
} else if (event.index() == 19) {
event.cancel(); // Description
}
}));
}
@Override
public void onMappingDataLoaded() {
mapTypes();
mapEntityTypeWithData(EntityTypes1_21_9.COPPER_GOLEM, EntityTypes1_21_9.FROG).tagName();
mapEntityTypeWithData(EntityTypes1_21_9.MANNEQUIN, EntityTypes1_21_9.PLAYER);
}
@Override
public EntityType typeFromId(final int type) {
return EntityTypes1_21_9.getTypeFromId(type);
}
}
@@ -0,0 +1,46 @@
/*
* 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.rewriter;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Particle;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.protocols.v1_21_7to1_21_9.packet.ClientboundPacket1_21_9;
import com.viaversion.viaversion.rewriter.ParticleRewriter;
public final class ParticleRewriter1_21_9 extends ParticleRewriter<ClientboundPacket1_21_9> {
public ParticleRewriter1_21_9(final Protocol<ClientboundPacket1_21_9, ?, ?, ?> protocol) {
super(protocol);
}
@Override
public void rewriteParticle(final UserConnection connection, final Particle particle) {
super.rewriteParticle(connection, particle);
final String identifier = protocol.getMappingData().getParticleMappings().mappedIdentifier(particle.id());
if ("minecraft:dragon_breath".equals(identifier)) {
particle.removeArgument(0); // Power
} else if ("minecraft:flash".equals(identifier)) {
particle.removeArgument(0); // Color
} else if ("minecraft:effect".equals(identifier) || "minecraft:instant_effect".equals(identifier)) {
particle.removeArgument(1); // Power
particle.removeArgument(0); // Color
}
}
}
@@ -0,0 +1,47 @@
/*
* 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.storage;
import java.util.UUID;
public final class MannequinData {
private final UUID uuid;
private final String name;
private boolean hasTeam;
public MannequinData(final UUID uuid, final String name) {
this.uuid = uuid;
this.name = name;
}
public void setHasTeam(final boolean hasTeam) {
this.hasTeam = hasTeam;
}
public boolean hasTeam() {
return hasTeam;
}
public UUID uuid() {
return uuid;
}
public String name() {
return name;
}
}
@@ -0,0 +1,38 @@
/*
* This file is part of ViaBackwards - https://github.com/ViaVersion/ViaBackwards
* Copyright (C) 2016-2025 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viabackwards.protocol.v1_21_9to1_21_7.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
public final class PlayerRotationStorage implements StorableObject {
private float yaw, pitch;
public void setRotation(final float yaw, final float pitch) {
this.yaw = yaw;
this.pitch = pitch;
}
public float yaw() {
return yaw;
}
public float pitch() {
return pitch;
}
}
@@ -0,0 +1,58 @@
/*
* 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.tracker;
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;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.entity.StoredEntityData;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.v1_21_5to1_21_6.packet.ClientboundPackets1_21_6;
import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class EntityTracker1_21_9 extends EntityTrackerBase {
public EntityTracker1_21_9(final UserConnection connection, @Nullable final EntityType playerType) {
super(connection, playerType);
}
@Override
public void removeEntity(final int id) {
sendRemovePacket(id);
super.removeEntity(id);
}
public void sendRemovePacket(final int id) {
final StoredEntityData entityData = entityDataIfPresent(id);
final MannequinData trackedEntityId;
if (entityData != null && (trackedEntityId = entityData.get(MannequinData.class)) != null) {
final PacketWrapper playerInfoRemove = PacketWrapper.create(ClientboundPackets1_21_6.PLAYER_INFO_REMOVE, user());
playerInfoRemove.write(Types.UUID_ARRAY, new UUID[]{trackedEntityId.uuid()});
playerInfoRemove.send(Protocol1_21_9To1_21_7.class);
final PacketWrapper removePlayerTeam = PacketWrapper.create(ClientboundPackets1_21_6.SET_PLAYER_TEAM, user());
removePlayerTeam.write(Types.STRING, trackedEntityId.name());
removePlayerTeam.write(Types.BYTE, (byte) 1); // Method
removePlayerTeam.send(Protocol1_21_9To1_21_7.class);
}
}
}
@@ -156,7 +156,7 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe
}
@Override
public Item handleItemToClient(final UserConnection connection, final Item item) {
public Item handleItemToClient(final UserConnection connection, Item item) {
if (item.isEmpty()) {
return item;
}
@@ -193,7 +193,7 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe
// Order is important
backupInconvertibleData(item);
super.handleItemToClient(connection, item);
item = super.handleItemToClient(connection, item);
downgradeItemData(item);
if (data.has(StructuredDataKey.RARITY)) {
@@ -209,7 +209,7 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe
}
@Override
public Item handleItemToServer(final UserConnection connection, final Item item) {
public Item handleItemToServer(final UserConnection connection, Item item) {
if (item.isEmpty()) {
return item;
}
@@ -226,7 +226,7 @@ public final class BlockItemPacketRewriter1_21 extends BackwardsStructuredItemRe
enchantmentRewriter.handleToServer(item);
// Order is important
super.handleItemToServer(connection, item);
item = super.handleItemToServer(connection, item);
updateItemData(item);
restoreInconvertibleData(item);
@@ -19,6 +19,7 @@ package com.viaversion.viabackwards.protocol.v1_21to1_20_5.rewriter;
import com.viaversion.nbt.tag.CompoundTag;
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_21to1_20_5.Protocol1_21To1_20_5;
import com.viaversion.viabackwards.protocol.v1_21to1_20_5.storage.EnchantmentsPaintingsStorage;
@@ -65,7 +66,7 @@ public final class EntityPacketRewriter1_21 extends EntityRewriter<ClientboundPa
registerSetEntityData(ClientboundPackets1_21.SET_ENTITY_DATA);
registerRemoveEntities(ClientboundPackets1_21.REMOVE_ENTITIES);
final RegistryDataRewriter registryDataRewriter = new RegistryDataRewriter(protocol);
final RegistryDataRewriter registryDataRewriter = new BackwardsRegistryRewriter(protocol);
protocol.registerClientbound(ClientboundConfigurationPackets1_21.REGISTRY_DATA, wrapper -> {
final String key = Key.stripMinecraftNamespace(wrapper.passthrough(Types.STRING));
final RegistryEntry[] entries = wrapper.passthrough(Types.REGISTRY_ENTRY_ARRAY);
@@ -0,0 +1,29 @@
/*
* 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.utils;
import com.viaversion.viabackwards.ViaBackwards;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.util.ProtocolLogger;
public final class BackwardsProtocolLogger extends ProtocolLogger {
public BackwardsProtocolLogger(final Class<? extends Protocol> protocol) {
super(ViaBackwards.getPlatform().getLogger(), protocol);
}
}
@@ -69,12 +69,6 @@ public final class ChatUtil {
public static CompoundTag translate(final String key) {
final CompoundTag tag = new CompoundTag();
tag.putString("translate", key);
return tag;
}
public static CompoundTag text(final String text) {
final CompoundTag tag = new CompoundTag();
tag.putString("text", text);
tag.putString("color", "white");
tag.putBoolean("italic", false);
return tag;
@@ -44,3 +44,19 @@ 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
#
# Dialog styling. You can also use translation keys here.
dialog-style:
page-navigation-title: "&9&lPage navigation"
page-navigation-next: "&9Left click: &6Go to next page"
page-navigation-previous: "&9Right click: &6Go to previous page"
toggle-value: "&9Left click: &6Toggle value"
increase-value: "&9Left click: &6Increase value by %s"
decrease-value: "&9Right click: &6Decrease value by %s"
value-range: "&7(Value between &a%s &7and &a%s&7)"
current-value: "&7Current value: &a%s"
edit-value: "&9Left click: &6Edit text"
next-option: "&9Left click: &6Go to next option"
previous-option: "&9Right click: &6Go to previous option"
set-text: "&9Left click/close: &6Set text"
close: "&9Left click: &6Close"
@@ -1,4 +1,174 @@
{
"1.21.9": {
"advMode.notEnabled.spawner": "Spawner blocks are not enabled",
"block.minecraft.acacia_shelf": "Acacia Shelf",
"block.minecraft.bamboo_shelf": "Bamboo Shelf",
"block.minecraft.birch_shelf": "Birch Shelf",
"block.minecraft.cherry_shelf": "Cherry Shelf",
"block.minecraft.copper_bars": "Copper Bars",
"block.minecraft.copper_chain": "Copper Chain",
"block.minecraft.copper_chest": "Copper Chest",
"block.minecraft.copper_golem_statue": "Copper Golem Statue",
"block.minecraft.copper_lantern": "Copper Lantern",
"block.minecraft.copper_torch": "Copper Torch",
"block.minecraft.copper_wall_torch": "Copper Wall Torch",
"block.minecraft.crimson_shelf": "Crimson Shelf",
"block.minecraft.dark_oak_shelf": "Dark Oak Shelf",
"block.minecraft.exposed_copper_bars": "Exposed Copper Bars",
"block.minecraft.exposed_copper_chain": "Exposed Copper Chain",
"block.minecraft.exposed_copper_chest": "Exposed Copper Chest",
"block.minecraft.exposed_copper_golem_statue": "Exposed Copper Golem Statue",
"block.minecraft.exposed_copper_lantern": "Exposed Copper Lantern",
"block.minecraft.exposed_lightning_rod": "Exposed Lightning Rod",
"block.minecraft.iron_chain": "Iron Chain",
"block.minecraft.jungle_shelf": "Jungle Shelf",
"block.minecraft.mangrove_shelf": "Mangrove Shelf",
"block.minecraft.oak_shelf": "Oak Shelf",
"block.minecraft.oxidized_copper_bars": "Oxidized Copper Bars",
"block.minecraft.oxidized_copper_chain": "Oxidized Copper Chain",
"block.minecraft.oxidized_copper_chest": "Oxidized Copper Chest",
"block.minecraft.oxidized_copper_golem_statue": "Oxidized Copper Golem Statue",
"block.minecraft.oxidized_copper_lantern": "Oxidized Copper Lantern",
"block.minecraft.oxidized_lightning_rod": "Oxidized Lightning Rod",
"block.minecraft.pale_oak_shelf": "Pale Oak Shelf",
"block.minecraft.spruce_shelf": "Spruce Shelf",
"block.minecraft.warped_shelf": "Warped Shelf",
"block.minecraft.waxed_copper_bars": "Waxed Copper Bars",
"block.minecraft.waxed_copper_chain": "Waxed Copper Chain",
"block.minecraft.waxed_copper_chest": "Waxed Copper Chest",
"block.minecraft.waxed_copper_golem_statue": "Waxed Copper Golem Statue",
"block.minecraft.waxed_copper_lantern": "Waxed Copper Lantern",
"block.minecraft.waxed_exposed_copper_bars": "Waxed Exposed Copper Bars",
"block.minecraft.waxed_exposed_copper_chain": "Waxed Exposed Copper Chain",
"block.minecraft.waxed_exposed_copper_chest": "Waxed Exposed Copper Chest",
"block.minecraft.waxed_exposed_copper_golem_statue": "Waxed Exposed Copper Golem Statue",
"block.minecraft.waxed_exposed_copper_lantern": "Waxed Exposed Copper Lantern",
"block.minecraft.waxed_exposed_lightning_rod": "Waxed Exposed Lightning Rod",
"block.minecraft.waxed_lightning_rod": "Waxed Lightning Rod",
"block.minecraft.waxed_oxidized_copper_bars": "Waxed Oxidized Copper Bars",
"block.minecraft.waxed_oxidized_copper_chain": "Waxed Oxidized Copper Chain",
"block.minecraft.waxed_oxidized_copper_chest": "Waxed Oxidized Copper Chest",
"block.minecraft.waxed_oxidized_copper_golem_statue": "Waxed Oxidized Copper Golem Statue",
"block.minecraft.waxed_oxidized_copper_lantern": "Waxed Oxidized Copper Lantern",
"block.minecraft.waxed_oxidized_lightning_rod": "Waxed Oxidized Lightning Rod",
"block.minecraft.waxed_weathered_copper_bars": "Waxed Weathered Copper Bars",
"block.minecraft.waxed_weathered_copper_chain": "Waxed Weathered Copper Chain",
"block.minecraft.waxed_weathered_copper_chest": "Waxed Weathered Copper Chest",
"block.minecraft.waxed_weathered_copper_golem_statue": "Waxed Weathered Copper Golem Statue",
"block.minecraft.waxed_weathered_copper_lantern": "Waxed Weathered Copper Lantern",
"block.minecraft.waxed_weathered_lightning_rod": "Waxed Weathered Lightning Rod",
"block.minecraft.weathered_copper_bars": "Weathered Copper Bars",
"block.minecraft.weathered_copper_chain": "Weathered Copper Chain",
"block.minecraft.weathered_copper_chest": "Weathered Copper Chest",
"block.minecraft.weathered_copper_golem_statue": "Weathered Copper Golem Statue",
"block.minecraft.weathered_copper_lantern": "Weathered Copper Lantern",
"block.minecraft.weathered_lightning_rod": "Weathered Lightning Rod",
"commands.fetchprofile.copy_component": "Copy Component",
"commands.fetchprofile.copy_text": "Copy %s",
"commands.fetchprofile.failed_to_serialize": "Failed to serialize profile: %s",
"commands.fetchprofile.give_item": "Give Item",
"commands.fetchprofile.id.failure": "Failed to resolve profile for ID %s",
"commands.fetchprofile.id.success": "Resolved profile for ID %s: %s",
"commands.fetchprofile.name.failure": "Failed to resolve profile for name %s",
"commands.fetchprofile.name.success": "Resolved profile for name %s: %s",
"commands.fetchprofile.summon_mannequin": "Summon Mannequin",
"commands.profile_fetch.copy_component": "Copy Component",
"commands.profile_fetch.failed_to_serialize": "Failed to serialize profile: %s",
"commands.profile_fetch.give_item": "Give Item",
"commands.profile_fetch.id.failure": "Failed to resolved profile for id %s",
"commands.profile_fetch.id.success": "Resolved profile for id %s: %s",
"commands.profile_fetch.name.failure": "Failed to resolve profile for name %s",
"commands.profile_fetch.name.success": "Resolved profile for name %s: %s",
"commands.setworldspawn.success.new": "Set the world spawn point to %s, %s, %s [%s, %s] in %s",
"commands.spawnpoint.success.multiple.new": "Set spawn point to %s, %s, %s [%s, %s] in %s for %s players",
"commands.spawnpoint.success.single.new": "Set spawn point to %s, %s, %s [%s, %s] in %s for %s",
"commands.spectate.cannot_spectate": "%s cannot be spectated",
"commands.summon.failed.peaceful": "Monsters cannot be summoned in Peaceful difficulty",
"component.profile.dynamic": "Dynamic",
"debug.entry.currently.alwaysOn": "%s: Currently always on",
"debug.entry.currently.inF3": "%s: Currently only in F3",
"debug.entry.currently.never": "%s: Currently off",
"debug.entry.f3": "In F3",
"debug.options.category.renderer": "Debug Renderers",
"debug.options.category.text": "Debug Screen Text",
"debug.options.help": "F3 + F6 = Edit debug options",
"debug.options.notAllowed.tooltip": "Not visible when debug info is reduced",
"debug.options.profile.default": "Default profile",
"debug.options.profile.performance": "Performance profile",
"debug.options.title": "Debug Options",
"debug.options.warning": "These options are for testing purposes only. They may slow down your computer, crash the game, or eat your pet rock.",
"entity.minecraft.copper_golem": "Copper Golem",
"entity.minecraft.mannequin": "Mannequin",
"entity.minecraft.mannequin.label": "NPC",
"gamerule.allowEnteringNetherUsingPortals": "Allow Nether",
"gamerule.allowEnteringNetherUsingPortals.description": "Controls whether players are allowed to enter the Nether.",
"gamerule.commandBlocksEnabled": "Enable Command Blocks",
"gamerule.enableCommandBlocks": "Enable Command Blocks",
"gamerule.pvp": "Enable pvp",
"gamerule.pvp.description": "Controls whether players are allowed to damage other players.",
"gamerule.spawnerBlocksEnabled": "Enable Spawner Blocks",
"gamerule.spawnMonsters.description": "Controls whether monsters naturally spawn.",
"gui.stats.none_found": "No statistics found.",
"item.minecraft.copper_axe": "Copper Axe",
"item.minecraft.copper_boots": "Copper Boots",
"item.minecraft.copper_chestplate": "Copper Chestplate",
"item.minecraft.copper_golem_spawn_egg": "Copper Golem Spawn Egg",
"item.minecraft.copper_helmet": "Copper Helmet",
"item.minecraft.copper_hoe": "Copper Hoe",
"item.minecraft.copper_horse_armor": "Copper Horse Armor",
"item.minecraft.copper_leggings": "Copper Leggings",
"item.minecraft.copper_nugget": "Copper Nugget",
"item.minecraft.copper_pickaxe": "Copper Pickaxe",
"item.minecraft.copper_shovel": "Copper Shovel",
"item.minecraft.copper_sword": "Copper Sword",
"item.spawn_egg.peaceful": "Disabled in Peaceful",
"key.spectatorHotbar": "Select On Hotbar",
"mco.configure.world.players.invite.duplicate": "A player with the provided name has already been invited to the Realm",
"multiplayer.codeOfConduct.check": "Do not notify again for this Code of Conduct",
"multiplayer.codeOfConduct.title": "Server Code of Conduct",
"multiplayer.confirm_command.run_command": "Run Command",
"multiplayer.confirm_command.signature_required": "You are trying to execute a command that will send chat messages using your name.\nIt can only be run from the chat screen\nCommand: %s",
"multiplayer.confirm_command.suggest_command": "Copy to Chat Screen",
"multiplayer.disconnect.banned.reason.default": "Banned by an operator.",
"multiplayer.disconnect.code_of_conduct": "Server requires accepting the Code of Conduct",
"multiplayer.disconnect.configuration_error": "Unexpected error during configuration",
"multiplayer.status.anonymous_player": "Anonymous Player",
"narration.slider.usage.focused.keyboard_cannot_change_value": "Press Enter to start changing the slider value",
"options.allowCursorChanges": "Allow Cursor Changes",
"options.allowCursorChanges.tooltip": "Allows the mouse cursor to change shape when over certain UI elements.",
"options.chat.drafts": "Save Unsent Chats",
"options.chat.drafts.tooltip": "Unsent messages will be saved and can be sent the next time chat is opened.",
"options.invertMouseX": "Invert Mouse X",
"options.invertMouseY": "Invert Mouse Y",
"options.showSubtitles.tooltip": "Enables captions for sounds played in the game.",
"options.sprintWindow": "Sprint Window",
"options.sprintWindow.tooltip": "Time window in ticks where double-tapping the forward key activates sprint.",
"pack.incompatible.confirm.unknown": "This pack is broken or made for an unknown version of Minecraft and may not work correctly.",
"pack.incompatible.unknown": "(Broken or incompatible)",
"subtitles.block.shelf.activate": "Shelf activates",
"subtitles.block.shelf.deactivate": "Shelf deactivates",
"subtitles.block.shelf.multi_swap": "Items swap",
"subtitles.block.shelf.place_item": "Item placed",
"subtitles.block.shelf.single_swap": "Item swaps",
"subtitles.block.shelf.take_item": "Item taken",
"subtitles.entity.copper_golem_become_statue": "Copper Golem is petrified",
"subtitles.entity.copper_golem_oxidized.death": "Copper Golem dies",
"subtitles.entity.copper_golem_oxidized.hurt": "Copper Golem hurts",
"subtitles.entity.copper_golem_oxidized.spin": "Copper Golem's head spins",
"subtitles.entity.copper_golem_weathered.death": "Copper Golem dies",
"subtitles.entity.copper_golem_weathered.hurt": "Copper Golem hurts",
"subtitles.entity.copper_golem_weathered.spin": "Copper Golem's head spins",
"subtitles.entity.copper_golem.death": "Copper Golem dies",
"subtitles.entity.copper_golem.hurt": "Copper Golem hurts",
"subtitles.entity.copper_golem.item_drop": "Copper Golem is placing an item",
"subtitles.entity.copper_golem.item_no_drop": "Copper Golem can't place item",
"subtitles.entity.copper_golem.no_item_get": "Copper Golem is picking up item",
"subtitles.entity.copper_golem.no_item_no_get": "Copper Golem can't pick up item",
"subtitles.entity.copper_golem.spawn": "Copper Golem appears",
"subtitles.entity.copper_golem.spin": "Copper Golem's head spins",
"subtitles.item.armor.equip_copper": "Copper armor clonks",
"subtitles.weather.end_flash": "End Flash rumbles"
},
"1.21.7": {
"item.minecraft.music_disc_lava_chicken.desc": "Hyper Potions - Lava Chicken",
"jukebox_song.minecraft.lava_chicken": "Hyper Potions - Lava Chicken",
+3 -3
View File
@@ -1,8 +1,8 @@
projectVersion=5.4.2
projectVersion=5.5.0
# Smile emoji (note that modrinth may not have added the version on release yet)
mcVersions=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.8
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
velocityVersion=3.4
org.gradle.configureondemand=true
+3 -3
View File
@@ -3,20 +3,20 @@ metadata.format.version = "1.1"
[versions]
# ViaVersion
viaver = "5.4.2-SNAPSHOT"
viaver = "5.5.0"
# Common provided
netty = "4.0.20.Final"
guava = "17.0"
log4j = "2.8.1"
checkerQual = "3.49.5"
checkerQual = "3.51.0"
# Platforms
paper = "1.16.5-R0.1-SNAPSHOT"
velocity = "3.1.1"
fabricLoader = "0.11.6"
viaProxy = "3.4.4-SNAPSHOT"
viaProxy = "3.4.5-SNAPSHOT"
[libraries]
Binary file not shown.
+2 -2
View File
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=845952a9d6afa783db70bb3b0effaae45ae5542ca2bb7929619e8af49cb634cf
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
distributionSha256Sum=a17ddd85a26b6a7f5ddb71ff8b05fc5104c0202c6e64782429790c933686c806
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+1 -4
View File
@@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
# Copyright © 2015 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -114,7 +114,6 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@@ -172,7 +171,6 @@ fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
Vendored
+1 -2
View File
@@ -70,11 +70,10 @@ goto fail
:execute
@rem Setup the command line
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
+4 -1
View File
@@ -2,6 +2,7 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
dependencyResolutionManagement {
repositories {
mavenLocal()
maven("https://repo.viaversion.com")
maven("https://repo.papermc.io/repository/maven-public/")
mavenCentral()
@@ -11,9 +12,11 @@ dependencyResolutionManagement {
pluginManagement {
plugins {
id("com.gradleup.shadow") version "9.1.0"
id("net.kyori.blossom") version "2.1.0"
id("org.jetbrains.gradle.plugin.idea-ext") version "1.2"
id("com.gradleup.shadow") version "8.3.8"
// A nice no-conflict comment for patching in downgrading
}
}
@@ -47,7 +47,7 @@
},
{
"id": "viaversion",
"version": "[5.0.4-SNAPSHOT,)"
"version": "[5.5.0-SNAPSHOT,)"
}
]
},
+2
View File
@@ -1,6 +1,8 @@
plugins {
id("io.papermc.hangar-publish-plugin") version "0.1.3"
id("com.modrinth.minotaur") version "2.+"
// A nice no-conflict comment for patching in downgrading
}
dependencies {