Compare commits

..
58 Commits
Author SHA1 Message Date
Nassim Jahnke f1b5f9223a 4.7.0 Release 2023-06-06 13:30:57 +02:00
Nassim Jahnke e4a1530aa8 Fix >1.18 vibration particle handling 2023-06-06 13:28:02 +02:00
Nassim Jahnke 09b67fad63 Small cleanup 2023-06-06 12:30:56 +02:00
Nassim Jahnke 1b3c5b4032 Create its own packets enum for 1.14.4
Acknowledge player digging was only added then, make sure this is represented correctly
2023-06-05 09:06:15 +02:00
Nassim Jahnke b7d8a3c8d5 1.20-rc1 2023-05-31 15:40:23 +02:00
Kichura 9a515df0f3 Update dependencies (#3332) 2023-05-30 09:25:18 +02:00
Nassim Jahnke c6103f2f51 1.20-pre7 2023-05-29 16:54:45 +02:00
Nassim Jahnke 5c0eda76e8 Don't replace unchanged 1.12->1.13 translations with hard text
Also add the remaining unchanged keys to the file
Fixes #3284
2023-05-28 13:48:22 +02:00
Nassim Jahnke 544a28b06b 1.20-pre6 2023-05-25 15:09:42 +02:00
RK_01 5c145d0184 Fixed high CPU usage on Java 8 (#3325)
Fixed https://bugs.openjdk.java.net/browse/JDK-8129861 by setting the core size of the TaskScheduler ThreadPool to 1
2023-05-23 18:18:10 +02:00
Nassim Jahnke ed55bccfe4 Fix 1.19.3->1.19.4 statistics handling
Fixes #3324
2023-05-23 16:39:20 +02:00
Nassim Jahnke 5acc2fefbc 1.20-pre5 2023-05-23 15:40:54 +02:00
Nassim Jahnke 7f748b5c68 1.20-pre4 2023-05-19 15:40:54 +02:00
Nassim Jahnke 0ec03f8b09 1.20-pre3 2023-05-19 14:22:14 +02:00
Nassim Jahnke a70034e0b5 Remove early static initializer call
Weird NoClassDefFoundError going on
2023-05-18 11:53:34 +02:00
Nassim Jahnke 98a0fdca94 1.20-pre2 2023-05-16 16:00:36 +02:00
Nassim JahnkeandPantera 82961cc153 Add 1.20 sound mappings
Co-authored-by: Pantera (Mad_Daniel) <89838384+Pantera07@users.noreply.github.com>
2023-05-14 08:42:51 +02:00
Nassim Jahnke 6c0d891c9f Don't print mapping validity warning if conversion warnings are disabled 2023-05-14 08:38:24 +02:00
Nassim Jahnke 6fa387e6ab Update the rest of nbt files to be uncompressed 2023-05-10 15:53:53 +02:00
Nassim Jahnke 07bdb57694 1.20-pre1 2023-05-10 15:46:03 +02:00
Nassim Jahnke 75dd79347a Update mappings 2023-05-05 21:05:35 +02:00
Nassim Jahnke 9257890d3c Update protocol version 2023-05-05 18:50:15 +02:00
Nassim Jahnke 891f55192d 23w18a, maybe 2023-05-03 15:21:24 +02:00
EnZaXD 7adadc0d21 added PlayerAbilities Provider (#3311) 2023-05-03 09:17:51 +02:00
Camotoy 638378cddf Let records properly stop in 1.19.3 -> 1.19.4 (#3308)
Fixes #3307
2023-04-28 14:44:29 +02:00
Nassim Jahnke 56d772df34 23w17a 2023-04-26 18:46:52 +02:00
Nassim Jahnke 7bb5cf3ae9 Update Gradle wrapper 2023-04-26 12:23:02 +02:00
Nassim Jahnke b67e3c30fd Move packet construction of schedule send methods to event loop as well
Fixes #3306
2023-04-26 12:18:08 +02:00
EnZaXD a2e214ae18 Improve InventoryTracker16 Code (#3302) 2023-04-22 08:57:47 +02:00
Nassim Jahnke 54d8e29a7e 23w16a 2023-04-20 17:28:30 +02:00
Joseph Burton a2daa9c989 Fix PlayerLookTargetProvider, apparently this packet is written in two different places (#3301) 2023-04-19 14:43:39 +02:00
Nassim Jahnke 74cc42fecf Merge remote-tracking branch 'origin/master' into dev 2023-04-19 12:08:15 +02:00
Joseph Burton dd59ddbd4f Add PlayerLookTargetProvider (#3299) 2023-04-19 12:04:17 +02:00
Nassim Jahnke bcfc77aa7d Merge branch 'master' into dev 2023-04-18 13:35:14 +02:00
Nassim Jahnke 1a46346789 Handle optional block state entity meta 2023-04-18 13:34:20 +02:00
RK_01 394be165fd Handle ENTITY_TELEPORT's targeting the client player (#3296) 2023-04-14 16:38:39 +02:00
Nassim Jahnke 20d86374b5 23w14a 2023-04-05 15:25:37 +02:00
Nassim Jahnke 8864b161f9 Print plugin name in unsupported software matching 2023-04-02 09:41:20 +02:00
Nassim Jahnke 7b0160d6c3 Fix redstone blockconnections
Fixes #3281
2023-03-31 16:41:06 +02:00
Nassim Jahnke 7e5173982d 23w13a 2023-03-29 16:32:50 +02:00
Nassim Jahnke ee75f19790 Merge branch 'master' into dev
# Conflicts:
#	gradle.properties
2023-03-29 16:28:57 +02:00
Nassim Jahnke e54f6d1999 Override metatypeimpl tostring 2023-03-28 17:27:22 +02:00
Nassim Jahnke c46bb5bcf5 Update Folia check 2023-03-25 00:31:50 +01:00
Nassim Jahnke d08f15c095 4.6.2 Release 2023-03-24 22:00:05 +01:00
Nassim Jahnke 8aa7898755 Cherry-pick some changes from dev 2023-03-24 17:58:53 +01:00
Nassim Jahnke 9682b68251 Handle sign nbt changes 2023-03-24 11:19:51 +01:00
Nassim Jahnke 364cfad9d8 23w12a 2023-03-22 18:49:18 +01:00
RK_01 641171a14f Properly handle dismount in PLAYER_POSITION packet (#3272) 2023-03-21 21:53:44 +01:00
Nassim Jahnke 23f045feee Fix glass pane and iron bars block connections
Fixes #3269
2023-03-20 10:31:13 +01:00
Nassim Jahnke f1bde8ba2a Handle shifted 1.19.4 boat types 2023-03-18 12:28:00 +01:00
Nassim Jahnke 9ccc3aed30 Keep all 1.12 translation mappings cached 2023-03-18 10:01:37 +01:00
Nassim Jahnke ad56caeb88 Double the trouble 2023-03-17 21:47:55 +01:00
Nassim Jahnke 573201c0b1 Only load JoinListener things early 2023-03-17 18:37:48 +01:00
Nassim Jahnke e298a7efac Fix protocol detection on some versions of Spigot
Fixes #3263
2023-03-17 18:36:48 +01:00
Nassim Jahnke 2e59a51734 Add PacketValue toString 2023-03-17 13:26:13 +01:00
Nassim Jahnke d4894ca4b5 Fix #3260 2023-03-17 13:15:56 +01:00
Nassim Jahnke 7f7c6241de Fix 1.12->1.13 stop sound handling
Fixes #3247
2023-03-17 11:37:37 +01:00
Nassim Jahnke 51606eb5ef Bump version to 4.6.2-SNAPSHOT 2023-03-17 11:34:35 +01:00
79 changed files with 1374 additions and 256 deletions

No files matched your search

+8 -3
View File
@@ -14,7 +14,6 @@ On Paper you may also use ProtocolSupport, but ensure you have the right build f
**User Docs:** https://docs.viaversion.com/display/VIAVERSION/
Sources
--------
**[OpenNBT](https://github.com/ViaVersion/OpenNBT)**
@@ -44,7 +43,9 @@ You can find official dev builds here:
**JavaDocs:** https://jd.viaversion.com
**Maven Repository:**
```xml
<repository>
<id>viaversion-repo</id>
<url>https://repo.viaversion.com</url>
@@ -52,7 +53,9 @@ You can find official dev builds here:
```
**API-artifact:**
```xml
<dependency>
<groupId>com.viaversion</groupId>
<artifactId>viaversion-api</artifactId>
@@ -69,7 +72,8 @@ Please note the [differences in licensing](#license).
Building
--------
After cloning this repository, build the project with Gradle by running `./gradlew build` and take the created jar out of
After cloning this repository, build the project with Gradle by running `./gradlew build` and take the created jar out
of
the `build/libs` directory.
@@ -80,7 +84,8 @@ Mapping files are generated and managed in our [Mappings repository](https://git
License
--------
The entirety of the [API directory](api) (including the legacy API directory) is licensed under the MIT License; see [licenses/MIT.md](licenses/MIT.md) for
The entirety of the [API directory](api) (including the legacy API directory) is licensed under the MIT License;
see [licenses/MIT.md](licenses/MIT.md) for
details.
Everything else, unless explicitly stated otherwise, is licensed under the GNU General Public License, including the end
@@ -85,6 +85,8 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_19 = register(759, "1.19");
public static final ProtocolVersion v1_19_1 = register(760, "1.19.1");
public static final ProtocolVersion v1_19_3 = register(761, "1.19.3");
public static final ProtocolVersion v1_19_4 = register(762, "1.19.4");
public static final ProtocolVersion v1_20 = register(763, "1.20");
public static final ProtocolVersion unknown = register(-1, "UNKNOWN");
public static ProtocolVersion register(int version, String name) {
@@ -101,6 +101,8 @@ public interface MappingData {
@Nullable Mappings getStatisticsMappings();
@Nullable Mappings getMenuMappings();
@Nullable Mappings getEnchantmentMappings();
@Nullable FullMappings getEntityMappings();
@@ -52,6 +52,7 @@ public class MappingDataBase implements MappingData {
protected Mappings statisticsMappings;
protected Mappings enchantmentMappings;
protected Mappings paintingMappings;
protected Mappings menuMappings;
protected Map<RegistryType, List<TagData>> tags;
public MappingDataBase(final String unmappedVersion, final String mappedVersion) {
@@ -71,6 +72,7 @@ public class MappingDataBase implements MappingData {
blockEntityMappings = loadMappings(data, "blockentities");
soundMappings = loadMappings(data, "sounds");
statisticsMappings = loadMappings(data, "statistics");
menuMappings = loadMappings(data, "menus");
enchantmentMappings = loadMappings(data, "enchantments");
paintingMappings = loadMappings(data, "paintings");
itemMappings = loadBiMappings(data, "items");
@@ -202,6 +204,11 @@ public class MappingDataBase implements MappingData {
return statisticsMappings;
}
@Override
public @Nullable Mappings getMenuMappings() {
return menuMappings;
}
@Override
public @Nullable Mappings getEnchantmentMappings() {
return enchantmentMappings;
@@ -236,7 +243,9 @@ public class MappingDataBase implements MappingData {
*/
protected int checkValidity(final int id, final int mappedId, final String type) {
if (mappedId == -1) {
getLogger().warning(String.format("Missing %s %s for %s %s %d", mappedVersion, type, unmappedVersion, type, id));
if (!Via.getConfig().isSuppressConversionWarnings()) {
getLogger().warning(String.format("Missing %s %s for %s %s %d", mappedVersion, type, unmappedVersion, type, id));
}
return 0;
}
return mappedId;
@@ -27,6 +27,10 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public interface BlockEntity {
static byte pack(int sectionX, int sectionZ) {
return (byte) (((sectionX) & 15) << 4 | (sectionZ & 15));
}
default byte sectionX() {
return (byte) ((packedXZ() >> 4) & 15);
}
@@ -63,6 +63,14 @@ public interface MetaType {
return type;
}
@Override
public String toString() {
return "MetaType{" +
"typeId=" + typeId +
", type=" + type +
'}';
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
@@ -22,6 +22,8 @@
*/
package com.viaversion.viaversion.api.platform;
import org.checkerframework.checker.nullness.qual.Nullable;
public interface UnsupportedSoftware {
/**
@@ -38,10 +40,19 @@ public interface UnsupportedSoftware {
*/
String getReason();
/**
* Returns the name of unsupported software if present.
*
* @return name of unsupported software if it is matched, else null
*/
@Nullable String match();
/**
* Returns whether the unsupported software is present.
*
* @return true if the unsupported software is found
*/
boolean findMatch();
default boolean findMatch() {
return match() != null;
}
}
@@ -83,6 +83,7 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_19_1 = register(760, "1.19.1/2", new VersionRange("1.19", 1, 2));
public static final ProtocolVersion v1_19_3 = register(761, "1.19.3");
public static final ProtocolVersion v1_19_4 = register(762, "1.19.4");
public static final ProtocolVersion v1_20 = register(763, "1.20");
public static final ProtocolVersion unknown = register(-1, "UNKNOWN");
public static ProtocolVersion register(int version, String name) {
@@ -237,6 +237,6 @@ public abstract class Type<T> implements ByteBufReader<T>, ByteBufWriter<T> {
@Override
public String toString() {
return "Type|" + typeName;
return typeName;
}
}
@@ -83,5 +83,13 @@ public class Particle {
public void setValue(Object value) {
this.value = value;
}
@Override
public String toString() {
return "ParticleData{" +
"type=" + type +
", value=" + value +
'}';
}
}
}
@@ -105,6 +105,7 @@ public class ParticleType extends Type<Particle> {
String resourceLocation = Type.STRING.read(buf);
particle.add(Type.STRING, resourceLocation);
resourceLocation = Key.stripMinecraftNamespace(resourceLocation);
if (resourceLocation.equals("block")) {
particle.add(Type.POSITION1_14, Type.POSITION1_14.read(buf)); // Target block pos
@@ -115,6 +116,21 @@ public class ParticleType extends Type<Particle> {
}
particle.add(Type.VAR_INT, Type.VAR_INT.readPrimitive(buf)); // Arrival in ticks
};
public static final ParticleReader VIBRATION1_19 = (buf, particle) -> {
String resourceLocation = Type.STRING.read(buf);
particle.add(Type.STRING, resourceLocation);
resourceLocation = Key.stripMinecraftNamespace(resourceLocation);
if (resourceLocation.equals("block")) {
particle.add(Type.POSITION1_14, Type.POSITION1_14.read(buf)); // Target block pos
} else if (resourceLocation.equals("entity")) {
particle.add(Type.VAR_INT, Type.VAR_INT.readPrimitive(buf)); // Target entity
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Y offset
} else {
Via.getPlatform().getLogger().warning("Unknown vibration path position source type: " + resourceLocation);
}
particle.add(Type.VAR_INT, Type.VAR_INT.readPrimitive(buf)); // Arrival in ticks
};
public static final ParticleReader SCULK_CHARGE = (buf, particle) -> {
particle.add(Type.FLOAT, Type.FLOAT.readPrimitive(buf)); // Roll
};
@@ -0,0 +1,38 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2023 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.metadata.types.MetaTypes1_19_4;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.MetaListType;
import com.viaversion.viaversion.api.type.types.minecraft.ParticleType;
import java.util.List;
public final class Types1_20 {
public static final ParticleType PARTICLE = new ParticleType(); // Only safe to use after protocol loading
public static final MetaTypes1_19_4 META_TYPES = new MetaTypes1_19_4(PARTICLE);
public static final Type<Metadata> METADATA = new MetadataType(META_TYPES);
public static final Type<List<Metadata>> METADATA_LIST = new MetaListType(METADATA);
}
@@ -36,7 +36,6 @@ import com.viaversion.viaversion.bukkit.platform.BukkitViaTask;
import com.viaversion.viaversion.bukkit.platform.BukkitViaTaskTask;
import com.viaversion.viaversion.bukkit.platform.PaperViaInjector;
import com.viaversion.viaversion.dump.PluginInfo;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ChatRewriter;
import com.viaversion.viaversion.unsupported.UnsupportedPlugin;
import com.viaversion.viaversion.unsupported.UnsupportedServerSoftware;
import com.viaversion.viaversion.util.GsonUtil;
@@ -56,7 +55,7 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player> {
private static final boolean FOLIA = PaperViaInjector.hasClass("io.papermc.paper.threadedregions.RegionisedServer");
private static final boolean FOLIA = PaperViaInjector.hasClass("io.papermc.paper.threadedregions.RegionizedServer");
private static ViaVersionPlugin instance;
private final BukkitCommandHandler commandHandler;
private final BukkitViaConfig conf;
@@ -81,15 +80,6 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player>
// Config magic
conf = new BukkitViaConfig();
// Load a bunch of classes early with slow reflection and more classloading
Via.getManager().getScheduler().execute(() -> {
if (conf.shouldRegisterUserConnectionOnJoin()) {
JoinListener.init();
}
ChatRewriter.init();
});
}
@Override
@@ -114,11 +104,11 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player>
}
if (FOLIA) {
// Use Folia's RegionisedServerInitEvent to run code after the server has loaded
// Use Folia's RegionizedServerInitEvent to run code after the server has loaded
final Class<? extends Event> serverInitEventClass;
try {
//noinspection unchecked
serverInitEventClass = (Class<? extends Event>) Class.forName("io.papermc.paper.threadedregions.RegionisedServerInitEvent");
serverInitEventClass = (Class<? extends Event>) Class.forName("io.papermc.paper.threadedregions.RegionizedServerInitEvent");
} catch (final ReflectiveOperationException e) {
throw new RuntimeException(e);
}
@@ -62,9 +62,6 @@ public class JoinListener implements Listener {
CHANNEL = channelField;
}
public static void init() {
}
// Loosely search a field with any name, as long as it matches a type name.
private static Field findField(Class<?> clazz, String... types) throws NoSuchFieldException {
for (Field field : clazz.getDeclaredFields()) {
@@ -31,28 +31,12 @@ import org.bukkit.inventory.PlayerInventory;
public final class ArmorToggleListener extends ViaBukkitListener {
private static final boolean ENABLED = hasEquipmentSlot();
public ArmorToggleListener(final ViaVersionPlugin plugin) {
super(plugin, Protocol1_19_4To1_19_3.class);
}
private static boolean hasEquipmentSlot() {
// Doesn't exist on 1.8
try {
Material.class.getMethod("getEquipmentSlot");
return true;
} catch (final NoSuchMethodException e) {
return false;
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void itemUse(final PlayerInteractEvent event) {
if (!ENABLED) {
return;
}
final Player player = event.getPlayer();
final ItemStack item = event.getItem();
if (item == null || event.getHand() == null || !isOnPipe(player)) {
@@ -36,7 +36,9 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class BukkitViaInjector extends LegacyViaInjector {
private static final boolean HAS_SHARED_CONSTANTS = PaperViaInjector.hasClass("net.minecraft.SharedConstants") && PaperViaInjector.hasClass("net.minecraft.WorldVersion");
private static final boolean HAS_WORLD_VERSION_PROTOCOL_VERSION = PaperViaInjector.hasClass("net.minecraft.SharedConstants")
&& PaperViaInjector.hasClass("net.minecraft.WorldVersion")
&& !PaperViaInjector.hasClass("com.mojang.bridge.game.GameVersion");
@Override
public void inject() throws ReflectiveOperationException {
@@ -65,7 +67,7 @@ public class BukkitViaInjector extends LegacyViaInjector {
return Bukkit.getUnsafe().getProtocolVersion();
}
return HAS_SHARED_CONSTANTS ? cursedProtocolDetection() : veryCursedProtocolDetection();
return HAS_WORLD_VERSION_PROTOCOL_VERSION ? cursedProtocolDetection() : veryCursedProtocolDetection();
}
private int cursedProtocolDetection() throws ReflectiveOperationException {
@@ -187,7 +189,7 @@ public class BukkitViaInjector extends LegacyViaInjector {
@Override
public boolean lateProtocolVersionSetting() {
return !(PaperViaInjector.PAPER_PROTOCOL_METHOD || HAS_SHARED_CONSTANTS);
return !(PaperViaInjector.PAPER_PROTOCOL_METHOD || HAS_WORLD_VERSION_PROTOCOL_VERSION);
}
public boolean isBinded() {
@@ -50,8 +50,10 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.scheduler.BukkitTask;
public class BukkitViaLoader implements ViaPlatformLoader {
@@ -144,7 +146,7 @@ public class BukkitViaLoader implements ViaPlatformLoader {
}
}
if (serverProtocolVersion < ProtocolVersion.v1_19_4.getVersion() && plugin.getConf().isArmorToggleFix()) {
if (serverProtocolVersion < ProtocolVersion.v1_19_4.getVersion() && plugin.getConf().isArmorToggleFix() && hasGetHandMethod()) {
new ArmorToggleListener(plugin).register();
}
@@ -195,6 +197,16 @@ public class BukkitViaLoader implements ViaPlatformLoader {
}
}
private boolean hasGetHandMethod() {
try {
PlayerInteractEvent.class.getDeclaredMethod("getHand");
Material.class.getMethod("getEquipmentSlot");
return true;
} catch (NoSuchMethodException e) {
return false;
}
}
@Override
public void unload() {
for (BukkitTask task : tasks) {
@@ -237,7 +237,8 @@ public class ViaManagerImpl implements ViaManager {
private void unsupportedSoftwareWarning() {
boolean found = false;
for (final UnsupportedSoftware software : platform.getUnsupportedSoftwareClasses()) {
if (!software.findMatch()) {
final String match = software.match();
if (match == null) {
continue;
}
@@ -249,7 +250,7 @@ public class ViaManagerImpl implements ViaManager {
found = true;
}
platform.getLogger().severe("We strongly advise against using " + software.getName() + ":");
platform.getLogger().severe("We strongly advise against using " + match + ":");
platform.getLogger().severe(software.getReason());
platform.getLogger().severe("");
}
@@ -70,6 +70,7 @@ import com.viaversion.viaversion.protocols.protocol1_19_1to1_19.Protocol1_19_1To
import com.viaversion.viaversion.protocols.protocol1_19_3to1_19_1.Protocol1_19_3To1_19_1;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.Protocol1_19_4To1_19_3;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
import com.viaversion.viaversion.protocols.protocol1_20to1_19_4.Protocol1_20To1_19_4;
import com.viaversion.viaversion.protocols.protocol1_9_1_2to1_9_3_4.Protocol1_9_1_2To1_9_3_4;
import com.viaversion.viaversion.protocols.protocol1_9_1to1_9.Protocol1_9_1To1_9;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.Protocol1_9_3To1_9_1_2;
@@ -180,6 +181,8 @@ public class ProtocolManagerImpl implements ProtocolManager {
registerProtocol(new Protocol1_19_1To1_19(), ProtocolVersion.v1_19_1, ProtocolVersion.v1_19);
registerProtocol(new Protocol1_19_3To1_19_1(), ProtocolVersion.v1_19_3, ProtocolVersion.v1_19_1);
registerProtocol(new Protocol1_19_4To1_19_3(), ProtocolVersion.v1_19_4, ProtocolVersion.v1_19_3);
registerProtocol(new Protocol1_20To1_19_4(), ProtocolVersion.v1_20, ProtocolVersion.v1_19_4);
}
@Override
@@ -39,6 +39,7 @@ import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import org.checkerframework.checker.nullness.qual.Nullable;
public class PacketWrapperImpl implements PacketWrapper {
@@ -265,20 +266,37 @@ public class PacketWrapperImpl implements PacketWrapper {
}
private void send0(Class<? extends Protocol> protocol, boolean skipCurrentPipeline, boolean currentThread) throws Exception {
if (isCancelled()) return;
try {
ByteBuf output = constructPacket(protocol, skipCurrentPipeline, Direction.CLIENTBOUND);
if (currentThread) {
user().sendRawPacket(output);
} else {
user().scheduleSendRawPacket(output);
}
} catch (Exception e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw e;
}
if (isCancelled()) {
return;
}
final UserConnection connection = user();
if (currentThread) {
try {
final ByteBuf output = constructPacket(protocol, skipCurrentPipeline, Direction.CLIENTBOUND);
connection.sendRawPacket(output);
} catch (final Exception e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw e;
}
}
return;
}
connection.getChannel().eventLoop().submit(() -> {
try {
final ByteBuf output = constructPacket(protocol, skipCurrentPipeline, Direction.CLIENTBOUND);
connection.sendRawPacket(output);
} catch (final RuntimeException e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw e;
}
} catch (final Exception e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw new RuntimeException(e);
}
}
});
}
/**
@@ -433,7 +451,9 @@ public class PacketWrapperImpl implements PacketWrapper {
}
private void sendToServerRaw(boolean currentThread) throws Exception {
if (isCancelled()) return;
if (isCancelled()) {
return;
}
ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer();
try {
@@ -463,18 +483,33 @@ public class PacketWrapperImpl implements PacketWrapper {
return;
}
try {
ByteBuf output = constructPacket(protocol, skipCurrentPipeline, Direction.SERVERBOUND);
if (currentThread) {
user().sendRawPacketToServer(output);
} else {
user().scheduleSendRawPacketToServer(output);
}
} catch (Exception e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw e;
final UserConnection connection = user();
if (currentThread) {
try {
final ByteBuf output = constructPacket(protocol, skipCurrentPipeline, Direction.SERVERBOUND);
connection.sendRawPacketToServer(output);
} catch (final Exception e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw e;
}
}
return;
}
connection.getChannel().eventLoop().submit(() -> {
try {
final ByteBuf output = constructPacket(protocol, skipCurrentPipeline, Direction.SERVERBOUND);
connection.sendRawPacketToServer(output);
} catch (final RuntimeException e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw e;
}
} catch (final Exception e) {
if (!PipelineUtil.containsCause(e, CancelException.class)) {
throw new RuntimeException(e);
}
}
});
}
@Override
@@ -508,10 +543,10 @@ public class PacketWrapperImpl implements PacketWrapper {
@Override
public String toString() {
return "PacketWrapper{" +
"packetType=" + packetType +
"type=" + packetType +
", id=" + id +
", packetValues=" + packetValues +
", readableObjects=" + readableObjects +
", values=" + packetValues +
", readable=" + readableObjects +
'}';
}
@@ -535,5 +570,26 @@ public class PacketWrapperImpl implements PacketWrapper {
public void setValue(@Nullable Object value) {
this.value = value;
}
@Override
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final PacketValue that = (PacketValue) o;
if (!type.equals(that.type)) return false;
return Objects.equals(value, that.value);
}
@Override
public int hashCode() {
int result = type.hashCode();
result = 31 * result + (value != null ? value.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "{" + type + ": " + value + "}";
}
}
}
@@ -18,6 +18,7 @@
package com.viaversion.viaversion.protocols.protocol1_13to1_12_2;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.libs.kyori.adventure.text.Component;
@@ -28,9 +29,15 @@ import com.viaversion.viaversion.libs.kyori.adventure.text.serializer.legacy.Leg
public final class ChatRewriter {
public static final GsonComponentSerializer HOVER_GSON_SERIALIZER = GsonComponentSerializer.builder().emitLegacyHoverEvent().legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.get()).build();
public static final JsonElement EMPTY_COMPONENT = GsonComponentSerializer.gson().serializeToTree(Component.empty());
public static void init() {
public static JsonObject emptyComponent() {
final JsonObject object = new JsonObject();
object.addProperty("text", "");
return object;
}
public static String emptyComponentString() {
return "{\"text\":\"\"}";
}
public static String legacyTextToJsonString(String message, boolean itemData) {
@@ -55,6 +55,7 @@ import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.packets.Inventor
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.packets.WorldPackets;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.BlockEntityProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PaintingProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.BlockConnectionStorage;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.BlockStorage;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage.TabCompleteTracker;
@@ -636,7 +637,8 @@ public class Protocol1_13To1_12_2 extends AbstractProtocol<ClientboundPackets1_1
// Fake the end of the packet
handler(wrapper -> {
wrapper.write(Type.BOOLEAN, false);
wrapper.write(Type.OPTIONAL_POSITION, null);
final Position playerLookTarget = Via.getManager().getProviders().get(PlayerLookTargetProvider.class).getPlayerLookTarget(wrapper.user());
wrapper.write(Type.OPTIONAL_POSITION, playerLookTarget);
if (!wrapper.isCancelled() && Via.getConfig().get1_13TabCompleteDelay() > 0) {
TabCompleteTracker tracker = wrapper.user().get(TabCompleteTracker.class);
wrapper.cancel();
@@ -876,6 +878,7 @@ public class Protocol1_13To1_12_2 extends AbstractProtocol<ClientboundPackets1_1
public void register(ViaProviders providers) {
providers.register(BlockEntityProvider.class, new BlockEntityProvider());
providers.register(PaintingProvider.class, new PaintingProvider());
providers.register(PlayerLookTargetProvider.class, new PlayerLookTargetProvider());
}
// Based on method from https://github.com/Bukkit/Bukkit/blob/master/src/main/java/org/bukkit/ChatColor.java
@@ -94,39 +94,38 @@ public class MappingData extends MappingDataBase {
}
}
Map<String, String> translateData = GsonUtil.getGson().fromJson(
Map<String, String> translationMappingData = GsonUtil.getGson().fromJson(
new InputStreamReader(MappingData.class.getClassLoader().getResourceAsStream("assets/viaversion/data/mapping-lang-1.12-1.13.json")),
new TypeToken<Map<String, String>>() {
}.getType());
try {
String[] lines;
try (Reader reader = new InputStreamReader(MappingData.class.getClassLoader()
.getResourceAsStream("assets/viaversion/data/en_US.properties"), StandardCharsets.UTF_8)) {
lines = CharStreams.toString(reader).split("\n");
}
for (String line : lines) {
if (line.isEmpty()) {
continue;
}
String[] keyAndTranslation = line.split("=", 2);
if (keyAndTranslation.length != 2) {
continue;
}
String key = keyAndTranslation[0];
if (!translateData.containsKey(key)) {
String translation = keyAndTranslation[1].replaceAll("%(\\d\\$)?d", "%$1s");
mojangTranslation.put(key, translation);
} else {
String dataValue = translateData.get(key);
if (dataValue != null) {
translateMapping.put(key, dataValue);
}
}
}
String[] unmappedTranslationLines;
try (Reader reader = new InputStreamReader(MappingData.class.getClassLoader()
.getResourceAsStream("assets/viaversion/data/en_US.properties"), StandardCharsets.UTF_8)) {
unmappedTranslationLines = CharStreams.toString(reader).split("\n");
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
for (String line : unmappedTranslationLines) {
if (line.isEmpty()) {
continue;
}
String[] keyAndTranslation = line.split("=", 2);
if (keyAndTranslation.length != 2) {
continue;
}
String key = keyAndTranslation[0];
String translation = keyAndTranslation[1].replaceAll("%(\\d\\$)?d", "%$1s").trim();
mojangTranslation.put(key, translation);
// Null values in the file mean the key did not change AND the translation has the same amount of placeholders still
if (translationMappingData.containsKey(key)) {
String mappedKey = translationMappingData.get(key);
translateMapping.put(key, mappedKey != null ? mappedKey : key);
}
}
}
@@ -106,7 +106,7 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_12_1, Ser
// Reset the packet
wrapper.clearPacket();
wrapper.setPacketType(ClientboundPackets1_13.SOUND);
wrapper.setPacketType(ClientboundPackets1_13.STOP_SOUND);
byte flags = 0;
wrapper.write(Type.BYTE, flags); // Placeholder
@@ -0,0 +1,30 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 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.viaversion.protocols.protocol1_13to1_12_2.providers;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.platform.providers.Provider;
import org.checkerframework.checker.nullness.qual.Nullable;
public class PlayerLookTargetProvider implements Provider {
@Nullable
public Position getPlayerLookTarget(final UserConnection info) {
return null;
}
}
@@ -17,12 +17,15 @@
*/
package com.viaversion.viaversion.protocols.protocol1_13to1_12_2.storage;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_12_1to1_12.ServerboundPackets1_12_1;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.providers.PlayerLookTargetProvider;
public class TabCompleteTracker implements StorableObject {
private int transactionId;
@@ -35,7 +38,8 @@ public class TabCompleteTracker implements StorableObject {
PacketWrapper wrapper = PacketWrapper.create(ServerboundPackets1_12_1.TAB_COMPLETE, null, connection);
wrapper.write(Type.STRING, lastTabComplete);
wrapper.write(Type.BOOLEAN, false);
wrapper.write(Type.OPTIONAL_POSITION, null);
final Position playerLookTarget = Via.getManager().getProviders().get(PlayerLookTargetProvider.class).getPlayerLookTarget(connection);
wrapper.write(Type.OPTIONAL_POSITION, playerLookTarget);
try {
wrapper.scheduleSendToServer(Protocol1_13To1_12_2.class);
} catch (Exception e) {
@@ -0,0 +1,127 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2023 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.viaversion.protocols.protocol1_14_4to1_14_3;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
public enum ClientboundPackets1_14_4 implements ClientboundPacketType {
SPAWN_ENTITY, // 0x00
SPAWN_EXPERIENCE_ORB, // 0x01
SPAWN_GLOBAL_ENTITY, // 0x02
SPAWN_MOB, // 0x03
SPAWN_PAINTING, // 0x04
SPAWN_PLAYER, // 0x05
ENTITY_ANIMATION, // 0x06
STATISTICS, // 0x07
BLOCK_BREAK_ANIMATION, // 0x08
BLOCK_ENTITY_DATA, // 0x09
BLOCK_ACTION, // 0x0A
BLOCK_CHANGE, // 0x0B
BOSSBAR, // 0x0C
SERVER_DIFFICULTY, // 0x0D
CHAT_MESSAGE, // 0x0E
MULTI_BLOCK_CHANGE, // 0x0F
TAB_COMPLETE, // 0x10
DECLARE_COMMANDS, // 0x11
WINDOW_CONFIRMATION, // 0x12
CLOSE_WINDOW, // 0x13
WINDOW_ITEMS, // 0x14
WINDOW_PROPERTY, // 0x15
SET_SLOT, // 0x16
COOLDOWN, // 0x17
PLUGIN_MESSAGE, // 0x18
NAMED_SOUND, // 0x19
DISCONNECT, // 0x1A
ENTITY_STATUS, // 0x1B
EXPLOSION, // 0x1C
UNLOAD_CHUNK, // 0x1D
GAME_EVENT, // 0x1E
OPEN_HORSE_WINDOW, // 0x1F
KEEP_ALIVE, // 0x20
CHUNK_DATA, // 0x21
EFFECT, // 0x22
SPAWN_PARTICLE, // 0x23
UPDATE_LIGHT, // 0x24
JOIN_GAME, // 0x25
MAP_DATA, // 0x26
TRADE_LIST, // 0x27
ENTITY_POSITION, // 0x28
ENTITY_POSITION_AND_ROTATION, // 0x29
ENTITY_ROTATION, // 0x2A
ENTITY_MOVEMENT, // 0x2B
VEHICLE_MOVE, // 0x2C
OPEN_BOOK, // 0x2D
OPEN_WINDOW, // 0x2E
OPEN_SIGN_EDITOR, // 0x2F
CRAFT_RECIPE_RESPONSE, // 0x30
PLAYER_ABILITIES, // 0x31
COMBAT_EVENT, // 0x32
PLAYER_INFO, // 0x33
FACE_PLAYER, // 0x34
PLAYER_POSITION, // 0x35
UNLOCK_RECIPES, // 0x36
DESTROY_ENTITIES, // 0x37
REMOVE_ENTITY_EFFECT, // 0x38
RESOURCE_PACK, // 0x39
RESPAWN, // 0x3A
ENTITY_HEAD_LOOK, // 0x3B
SELECT_ADVANCEMENTS_TAB, // 0x3C
WORLD_BORDER, // 0x3D
CAMERA, // 0x3E
HELD_ITEM_CHANGE, // 0x3F
UPDATE_VIEW_POSITION, // 0x40
UPDATE_VIEW_DISTANCE, // 0x41
DISPLAY_SCOREBOARD, // 0x42
ENTITY_METADATA, // 0x43
ATTACH_ENTITY, // 0x44
ENTITY_VELOCITY, // 0x45
ENTITY_EQUIPMENT, // 0x46
SET_EXPERIENCE, // 0x47
UPDATE_HEALTH, // 0x48
SCOREBOARD_OBJECTIVE, // 0x49
SET_PASSENGERS, // 0x4A
TEAMS, // 0x4B
UPDATE_SCORE, // 0x4C
SPAWN_POSITION, // 0x4D
TIME_UPDATE, // 0x4E
TITLE, // 0x4F
ENTITY_SOUND, // 0x50
SOUND, // 0x51
STOP_SOUND, // 0x52
TAB_LIST, // 0x53
NBT_QUERY, // 0x54
COLLECT_ITEM, // 0x55
ENTITY_TELEPORT, // 0x56
ADVANCEMENTS, // 0x57
ENTITY_PROPERTIES, // 0x58
ENTITY_EFFECT, // 0x59
DECLARE_RECIPES, // 0x5A
TAGS, // 0x5B
ACKNOWLEDGE_PLAYER_DIGGING; // 0x5C
@Override
public int getId() {
return ordinal();
}
@Override
public String getName() {
return name();
}
}
@@ -22,10 +22,10 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ServerboundPackets1_14;
public class Protocol1_14_4To1_14_3 extends AbstractProtocol<ClientboundPackets1_14, ClientboundPackets1_14, ServerboundPackets1_14, ServerboundPackets1_14> {
public class Protocol1_14_4To1_14_3 extends AbstractProtocol<ClientboundPackets1_14, ClientboundPackets1_14_4, ServerboundPackets1_14, ServerboundPackets1_14> {
public Protocol1_14_4To1_14_3() {
super(ClientboundPackets1_14.class, ClientboundPackets1_14.class, null, null);
super(ClientboundPackets1_14.class, ClientboundPackets1_14_4.class, null, null);
}
@Override
@@ -112,8 +112,7 @@ public enum ClientboundPackets1_14 implements ClientboundPacketType {
ENTITY_PROPERTIES, // 0x58
ENTITY_EFFECT, // 0x59
DECLARE_RECIPES, // 0x5A
TAGS, // 0x5B
ACKNOWLEDGE_PLAYER_DIGGING; // 0x5C
TAGS; // 0x5B
@Override
public int getId() {
@@ -25,7 +25,7 @@ import com.viaversion.viaversion.api.minecraft.entities.Entity1_15Types;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_14_4to1_14_3.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ServerboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.metadata.MetadataRewriter1_15To1_14_4;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.packets.EntityPackets;
@@ -35,15 +35,15 @@ import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
public class Protocol1_15To1_14_4 extends AbstractProtocol<ClientboundPackets1_14, ClientboundPackets1_15, ServerboundPackets1_14, ServerboundPackets1_14> {
public class Protocol1_15To1_14_4 extends AbstractProtocol<ClientboundPackets1_14_4, ClientboundPackets1_15, ServerboundPackets1_14, ServerboundPackets1_14> {
public static final MappingData MAPPINGS = new MappingDataBase("1.14", "1.15");
private final MetadataRewriter1_15To1_14_4 metadataRewriter = new MetadataRewriter1_15To1_14_4(this);
private final InventoryPackets itemRewriter = new InventoryPackets(this);
private TagRewriter<ClientboundPackets1_14> tagRewriter;
private TagRewriter<ClientboundPackets1_14_4> tagRewriter;
public Protocol1_15To1_14_4() {
super(ClientboundPackets1_14.class, ClientboundPackets1_15.class, ServerboundPackets1_14.class, ServerboundPackets1_14.class);
super(ClientboundPackets1_14_4.class, ClientboundPackets1_15.class, ServerboundPackets1_14.class, ServerboundPackets1_14.class);
}
@Override
@@ -54,16 +54,16 @@ public class Protocol1_15To1_14_4 extends AbstractProtocol<ClientboundPackets1_1
EntityPackets.register(this);
WorldPackets.register(this);
SoundRewriter<ClientboundPackets1_14> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound(ClientboundPackets1_14.ENTITY_SOUND); // Entity Sound Effect (added somewhere in 1.14)
soundRewriter.registerSound(ClientboundPackets1_14.SOUND);
SoundRewriter<ClientboundPackets1_14_4> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound(ClientboundPackets1_14_4.ENTITY_SOUND); // Entity Sound Effect (added somewhere in 1.14)
soundRewriter.registerSound(ClientboundPackets1_14_4.SOUND);
new StatisticsRewriter<>(this).register(ClientboundPackets1_14.STATISTICS);
new StatisticsRewriter<>(this).register(ClientboundPackets1_14_4.STATISTICS);
registerServerbound(ServerboundPackets1_14.EDIT_BOOK, wrapper -> itemRewriter.handleItemToServer(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)));
tagRewriter = new TagRewriter<>(this);
tagRewriter.register(ClientboundPackets1_14.TAGS, RegistryType.ENTITY);
tagRewriter.register(ClientboundPackets1_14_4.TAGS, RegistryType.ENTITY);
}
@Override
@@ -24,13 +24,13 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.type.types.Particle;
import com.viaversion.viaversion.api.type.types.version.Types1_14;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_14_4to1_14_3.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.packets.EntityPackets;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import java.util.List;
public class MetadataRewriter1_15To1_14_4 extends EntityRewriter<ClientboundPackets1_14, Protocol1_15To1_14_4> {
public class MetadataRewriter1_15To1_14_4 extends EntityRewriter<ClientboundPackets1_14_4, Protocol1_15To1_14_4> {
public MetadataRewriter1_15To1_14_4(Protocol1_15To1_14_4 protocol) {
super(protocol);
@@ -24,21 +24,21 @@ import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_14;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_14_4to1_14_3.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.ClientboundPackets1_15;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.metadata.MetadataRewriter1_15To1_14_4;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import java.util.List;
public class EntityPackets {
public final class EntityPackets {
public static void register(Protocol1_15To1_14_4 protocol) {
MetadataRewriter1_15To1_14_4 metadataRewriter = protocol.get(MetadataRewriter1_15To1_14_4.class);
metadataRewriter.registerTrackerWithData(ClientboundPackets1_14.SPAWN_ENTITY, Entity1_15Types.FALLING_BLOCK);
metadataRewriter.registerTrackerWithData(ClientboundPackets1_14_4.SPAWN_ENTITY, Entity1_15Types.FALLING_BLOCK);
protocol.registerClientbound(ClientboundPackets1_14.SPAWN_MOB, new PacketHandlers() {
protocol.registerClientbound(ClientboundPackets1_14_4.SPAWN_MOB, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // 0 - Entity ID
@@ -59,7 +59,7 @@ public class EntityPackets {
}
});
protocol.registerClientbound(ClientboundPackets1_14.SPAWN_PLAYER, new PacketHandlers() {
protocol.registerClientbound(ClientboundPackets1_14_4.SPAWN_PLAYER, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // 0 - Entity ID
@@ -79,7 +79,7 @@ public class EntityPackets {
}
});
protocol.registerClientbound(ClientboundPackets1_14.RESPAWN, new PacketHandlers() {
protocol.registerClientbound(ClientboundPackets1_14_4.RESPAWN, new PacketHandlers() {
@Override
public void register() {
map(Type.INT);
@@ -87,7 +87,7 @@ public class EntityPackets {
}
});
protocol.registerClientbound(ClientboundPackets1_14.JOIN_GAME, new PacketHandlers() {
protocol.registerClientbound(ClientboundPackets1_14_4.JOIN_GAME, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // 0 - Entity ID
@@ -105,8 +105,8 @@ public class EntityPackets {
}
});
metadataRewriter.registerMetadataRewriter(ClientboundPackets1_14.ENTITY_METADATA, Types1_14.METADATA_LIST);
metadataRewriter.registerRemoveEntities(ClientboundPackets1_14.DESTROY_ENTITIES);
metadataRewriter.registerMetadataRewriter(ClientboundPackets1_14_4.ENTITY_METADATA, Types1_14.METADATA_LIST);
metadataRewriter.registerRemoveEntities(ClientboundPackets1_14_4.DESTROY_ENTITIES);
}
private static void sendMetadataPacket(PacketWrapper wrapper, int entityId, EntityRewriter<?, ?> rewriter) throws Exception {
@@ -18,13 +18,13 @@
package com.viaversion.viaversion.protocols.protocol1_15to1_14_4.packets;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_14_4to1_14_3.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ServerboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
import com.viaversion.viaversion.rewriter.ItemRewriter;
import com.viaversion.viaversion.rewriter.RecipeRewriter;
public class InventoryPackets extends ItemRewriter<ClientboundPackets1_14, ServerboundPackets1_14, Protocol1_15To1_14_4> {
public class InventoryPackets extends ItemRewriter<ClientboundPackets1_14_4, ServerboundPackets1_14, Protocol1_15To1_14_4> {
public InventoryPackets(Protocol1_15To1_14_4 protocol) {
super(protocol);
@@ -32,14 +32,14 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_14, Serve
@Override
public void registerPackets() {
registerSetCooldown(ClientboundPackets1_14.COOLDOWN);
registerWindowItems(ClientboundPackets1_14.WINDOW_ITEMS, Type.FLAT_VAR_INT_ITEM_ARRAY);
registerTradeList(ClientboundPackets1_14.TRADE_LIST);
registerSetSlot(ClientboundPackets1_14.SET_SLOT, Type.FLAT_VAR_INT_ITEM);
registerEntityEquipment(ClientboundPackets1_14.ENTITY_EQUIPMENT, Type.FLAT_VAR_INT_ITEM);
registerAdvancements(ClientboundPackets1_14.ADVANCEMENTS, Type.FLAT_VAR_INT_ITEM);
registerSetCooldown(ClientboundPackets1_14_4.COOLDOWN);
registerWindowItems(ClientboundPackets1_14_4.WINDOW_ITEMS, Type.FLAT_VAR_INT_ITEM_ARRAY);
registerTradeList(ClientboundPackets1_14_4.TRADE_LIST);
registerSetSlot(ClientboundPackets1_14_4.SET_SLOT, Type.FLAT_VAR_INT_ITEM);
registerEntityEquipment(ClientboundPackets1_14_4.ENTITY_EQUIPMENT, Type.FLAT_VAR_INT_ITEM);
registerAdvancements(ClientboundPackets1_14_4.ADVANCEMENTS, Type.FLAT_VAR_INT_ITEM);
new RecipeRewriter<>(protocol).register(ClientboundPackets1_14.DECLARE_RECIPES);
new RecipeRewriter<>(protocol).register(ClientboundPackets1_14_4.DECLARE_RECIPES);
registerClickWindow(ServerboundPackets1_14.CLICK_WINDOW, Type.FLAT_VAR_INT_ITEM);
registerCreativeInvAction(ServerboundPackets1_14.CREATIVE_INVENTORY_ACTION, Type.FLAT_VAR_INT_ITEM);
@@ -23,23 +23,23 @@ import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import com.viaversion.viaversion.protocols.protocol1_14_4to1_14_3.ClientboundPackets1_14_4;
import com.viaversion.viaversion.protocols.protocol1_14to1_13_2.types.Chunk1_14Type;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
import com.viaversion.viaversion.protocols.protocol1_15to1_14_4.types.Chunk1_15Type;
import com.viaversion.viaversion.rewriter.BlockRewriter;
public class WorldPackets {
public final class WorldPackets {
public static void register(Protocol1_15To1_14_4 protocol) {
BlockRewriter<ClientboundPackets1_14> blockRewriter = new BlockRewriter<>(protocol, Type.POSITION1_14);
BlockRewriter<ClientboundPackets1_14_4> blockRewriter = new BlockRewriter<>(protocol, Type.POSITION1_14);
blockRewriter.registerBlockAction(ClientboundPackets1_14.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_14.BLOCK_CHANGE);
blockRewriter.registerMultiBlockChange(ClientboundPackets1_14.MULTI_BLOCK_CHANGE);
blockRewriter.registerAcknowledgePlayerDigging(ClientboundPackets1_14.ACKNOWLEDGE_PLAYER_DIGGING);
blockRewriter.registerBlockAction(ClientboundPackets1_14_4.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_14_4.BLOCK_CHANGE);
blockRewriter.registerMultiBlockChange(ClientboundPackets1_14_4.MULTI_BLOCK_CHANGE);
blockRewriter.registerAcknowledgePlayerDigging(ClientboundPackets1_14_4.ACKNOWLEDGE_PLAYER_DIGGING);
protocol.registerClientbound(ClientboundPackets1_14.CHUNK_DATA, wrapper -> {
protocol.registerClientbound(ClientboundPackets1_14_4.CHUNK_DATA, wrapper -> {
Chunk chunk = wrapper.read(new Chunk1_14Type());
wrapper.write(new Chunk1_15Type(), chunk);
@@ -79,8 +79,8 @@ public class WorldPackets {
}
});
blockRewriter.registerEffect(ClientboundPackets1_14.EFFECT, 1010, 2001);
protocol.registerClientbound(ClientboundPackets1_14.SPAWN_PARTICLE, new PacketHandlers() {
blockRewriter.registerEffect(ClientboundPackets1_14_4.EFFECT, 1010, 2001);
protocol.registerClientbound(ClientboundPackets1_14_4.SPAWN_PARTICLE, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // 0 - Particle ID
@@ -40,8 +40,7 @@ public class MappingData extends MappingDataBase {
@Override
public void loadExtras(final CompoundTag data) {
try {
// TODO Read uncompressed file
dimensionRegistry = BinaryTagIO.readCompressedInputStream(MappingDataLoader.getResource("dimension-registry-1.16.2.nbt"));
dimensionRegistry = BinaryTagIO.readInputStream(MappingDataLoader.getResource("dimension-registry-1.16.2.nbt"));
} catch (final IOException e) {
Via.getPlatform().getLogger().severe("Error loading dimension registry:");
e.printStackTrace();
@@ -25,6 +25,7 @@ import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.RegistryType;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_16Types;
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
@@ -40,6 +41,7 @@ import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.metadata.Metadat
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.packets.EntityPackets;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.packets.InventoryPackets;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.packets.WorldPackets;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.provider.PlayerAbilitiesProvider;
import com.viaversion.viaversion.protocols.protocol1_16to1_15_2.storage.InventoryTracker1_16;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
@@ -195,10 +197,11 @@ public class Protocol1_16To1_15_2 extends AbstractProtocol<ClientboundPackets1_1
}
registerServerbound(ServerboundPackets1_16.PLAYER_ABILITIES, wrapper -> {
wrapper.passthrough(Type.BYTE);
// Flying and walking speed - not important anyways
wrapper.write(Type.FLOAT, 0.05F);
wrapper.write(Type.FLOAT, 0.1F);
wrapper.passthrough(Type.BYTE); // Flags
final PlayerAbilitiesProvider playerAbilities = Via.getManager().getProviders().get(PlayerAbilitiesProvider.class);
wrapper.write(Type.FLOAT, playerAbilities.getFlyingSpeed(wrapper.user()));
wrapper.write(Type.FLOAT, playerAbilities.getWalkingSpeed(wrapper.user()));
});
cancelServerbound(ServerboundPackets1_16.GENERATE_JIGSAW);
@@ -257,6 +260,11 @@ public class Protocol1_16To1_15_2 extends AbstractProtocol<ClientboundPackets1_1
.reader("item", ParticleType.Readers.VAR_INT_ITEM);
}
@Override
public void register(ViaProviders providers) {
providers.register(PlayerAbilitiesProvider.class, new PlayerAbilitiesProvider());
}
@Override
public void init(UserConnection userConnection) {
userConnection.addEntityTracker(this.getClass(), new EntityTrackerBase(userConnection, Entity1_16Types.PLAYER));
@@ -277,7 +277,7 @@ public class EntityPackets {
protocol.registerServerbound(ServerboundPackets1_16.ANIMATION, wrapper -> {
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
// Don't send an arm swing if the player has an inventory opened.
if (inventoryTracker.getInventory() != -1) {
if (inventoryTracker.isInventoryOpen()) {
wrapper.cancel();
}
});
@@ -67,12 +67,11 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_15, Serve
handler(cursorRemapper);
handler(wrapper -> {
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
int windowId = wrapper.get(Type.VAR_INT, 0);
int windowType = wrapper.get(Type.VAR_INT, 1);
if (windowType >= 20) { // smithing added with id 20
wrapper.set(Type.VAR_INT, 1, ++windowType);
}
inventoryTracker.setInventory((short) windowId);
inventoryTracker.setInventoryOpen(true);
});
}
});
@@ -83,7 +82,7 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_15, Serve
handler(cursorRemapper);
handler(wrapper -> {
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
inventoryTracker.setInventory((short) -1);
inventoryTracker.setInventoryOpen(false);
});
}
});
@@ -133,7 +132,7 @@ public class InventoryPackets extends ItemRewriter<ClientboundPackets1_15, Serve
protocol.registerServerbound(ServerboundPackets1_16.CLOSE_WINDOW, wrapper -> {
InventoryTracker1_16 inventoryTracker = wrapper.user().get(InventoryTracker1_16.class);
inventoryTracker.setInventory((short) -1);
inventoryTracker.setInventoryOpen(false);
});
protocol.registerServerbound(ServerboundPackets1_16.EDIT_BOOK, wrapper -> handleItemToServer(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)));
@@ -0,0 +1,32 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 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.viaversion.protocols.protocol1_16to1_15_2.provider;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.platform.providers.Provider;
public class PlayerAbilitiesProvider implements Provider {
public float getFlyingSpeed(final UserConnection connection) {
return 0.05F;
}
public float getWalkingSpeed(final UserConnection connection) {
return 0.1F;
}
}
@@ -20,13 +20,13 @@ package com.viaversion.viaversion.protocols.protocol1_16to1_15_2.storage;
import com.viaversion.viaversion.api.connection.StorableObject;
public class InventoryTracker1_16 implements StorableObject {
private short inventory = -1;
private boolean inventoryOpen = false;
public short getInventory() {
return this.inventory;
public boolean isInventoryOpen() {
return inventoryOpen;
}
public void setInventory(short inventory) {
this.inventory = inventory;
public void setInventoryOpen(boolean inventoryOpen) {
this.inventoryOpen = inventoryOpen;
}
}
@@ -162,7 +162,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_16_2
}
}
});
registerMetaTypeHandler(Types1_17.META_TYPES.itemType, Types1_17.META_TYPES.blockStateType, Types1_17.META_TYPES.particleType);
registerMetaTypeHandler(Types1_17.META_TYPES.itemType, Types1_17.META_TYPES.blockStateType, null, Types1_17.META_TYPES.particleType);
// Ticks frozen added with id 7
filter().filterFamily(Entity1_17Types.ENTITY).addIndex(7);
@@ -96,7 +96,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_17_1
}
});
registerMetaTypeHandler(Types1_18.META_TYPES.itemType, null, null);
registerMetaTypeHandler(Types1_18.META_TYPES.itemType, null, null, null);
}
@Override
@@ -289,7 +289,7 @@ public final class Protocol1_19_3To1_19_1 extends AbstractProtocol<ClientboundPa
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
.reader("item", ParticleType.Readers.VAR_INT_ITEM)
.reader("vibration", ParticleType.Readers.VIBRATION)
.reader("vibration", ParticleType.Readers.VIBRATION1_19)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK);
Entity1_19_3Types.initialize(this);
@@ -155,7 +155,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_1
final int id = meta.metaType().typeId();
meta.setMetaType(Types1_19_3.META_TYPES.byId(id >= 2 ? id + 1 : id)); // long added
});
registerMetaTypeHandler(Types1_19_3.META_TYPES.itemType, Types1_19_3.META_TYPES.blockStateType, Types1_19_3.META_TYPES.particleType);
registerMetaTypeHandler(Types1_19_3.META_TYPES.itemType, Types1_19_3.META_TYPES.blockStateType, null, Types1_19_3.META_TYPES.particleType);
filter().index(6).handler((event, meta) -> {
// Sitting pose added
@@ -26,16 +26,16 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_19_4;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.libs.kyori.adventure.text.Component;
import com.viaversion.viaversion.libs.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ChatRewriter;
import com.viaversion.viaversion.protocols.protocol1_19_3to1_19_1.ClientboundPackets1_19_3;
import com.viaversion.viaversion.protocols.protocol1_19_3to1_19_1.ServerboundPackets1_19_3;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.data.MappingData;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.packets.EntityPackets;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.packets.InventoryPackets;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.storage.PlayerVehicleTracker;
import com.viaversion.viaversion.rewriter.CommandRewriter;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
@@ -55,6 +55,7 @@ public final class Protocol1_19_4To1_19_3 extends AbstractProtocol<ClientboundPa
super.registerPackets();
new TagRewriter<>(this).registerGeneric(ClientboundPackets1_19_3.TAGS);
new StatisticsRewriter<>(this).register(ClientboundPackets1_19_3.STATISTICS);
final SoundRewriter<ClientboundPackets1_19_3> soundRewriter = new SoundRewriter<>(this);
soundRewriter.registerSound(ClientboundPackets1_19_3.ENTITY_SOUND);
@@ -77,11 +78,14 @@ public final class Protocol1_19_4To1_19_3 extends AbstractProtocol<ClientboundPa
if (element != null) {
wrapper.write(Type.COMPONENT, element);
} else {
wrapper.write(Type.COMPONENT, ChatRewriter.EMPTY_COMPONENT);
wrapper.write(Type.COMPONENT, ChatRewriter.emptyComponent());
}
final String iconBase64 = wrapper.read(Type.OPTIONAL_STRING);
final byte[] iconBytes = iconBase64 != null ? Base64.getDecoder().decode(iconBase64.substring("data:image/png;base64,".length()).getBytes(StandardCharsets.UTF_8)) : null;
byte[] iconBytes = null;
if (iconBase64 != null && iconBase64.startsWith("data:image/png;base64,")) {
iconBytes = Base64.getDecoder().decode(iconBase64.substring("data:image/png;base64,".length()).getBytes(StandardCharsets.UTF_8));
}
wrapper.write(Type.OPTIONAL_BYTE_ARRAY_PRIMITIVE, iconBytes);
});
}
@@ -97,7 +101,7 @@ public final class Protocol1_19_4To1_19_3 extends AbstractProtocol<ClientboundPa
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
.reader("item", ParticleType.Readers.VAR_INT_ITEM)
.reader("vibration", ParticleType.Readers.VIBRATION)
.reader("vibration", ParticleType.Readers.VIBRATION1_19)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK);
}
@@ -105,6 +109,8 @@ public final class Protocol1_19_4To1_19_3 extends AbstractProtocol<ClientboundPa
@Override
public void init(final UserConnection user) {
addEntityTracker(user, new EntityTrackerBase(user, Entity1_19_4Types.PLAYER));
user.put(new PlayerVehicleTracker(user));
}
@Override
@@ -121,4 +127,4 @@ public final class Protocol1_19_4To1_19_3 extends AbstractProtocol<ClientboundPa
public InventoryPackets getItemRewriter() {
return itemRewriter;
}
}
}
@@ -34,8 +34,7 @@ public final class MappingData extends MappingDataBase {
@Override
protected void loadExtras(final CompoundTag data) {
try {
// TODO Read uncompressed file
damageTypesRegistry = BinaryTagIO.readCompressedInputStream(MappingDataLoader.getResource("damage-types-1.19.4.nbt"));
damageTypesRegistry = BinaryTagIO.readInputStream(MappingDataLoader.getResource("damage-types-1.19.4.nbt"));
} catch (final IOException e) {
throw new RuntimeException(e);
}
@@ -24,6 +24,7 @@ import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_19_4Types;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_19_3;
@@ -31,6 +32,7 @@ import com.viaversion.viaversion.api.type.types.version.Types1_19_4;
import com.viaversion.viaversion.protocols.protocol1_19_3to1_19_1.ClientboundPackets1_19_3;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.Protocol1_19_4To1_19_3;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.storage.PlayerVehicleTracker;
import com.viaversion.viaversion.rewriter.EntityRewriter;
public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_3, Protocol1_19_4To1_19_3> {
@@ -55,6 +57,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_3
handler(dimensionDataHandler());
handler(biomeSizeTracker());
handler(worldDataTrackerHandlerByKey());
handler(playerTrackerHandler());
handler(wrapper -> {
final CompoundTag registry = wrapper.get(Type.NBT, 0);
final CompoundTag damageTypeRegistry = protocol.getMappingData().damageTypesRegistry();
@@ -82,7 +85,74 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_3
map(Type.FLOAT); // Pitch
map(Type.BYTE); // Relative arguments
map(Type.VAR_INT); // Id
read(Type.BOOLEAN); // Dismount vehicle
handler(wrapper -> {
if (wrapper.read(Type.BOOLEAN)) { // Dismount vehicle
final PlayerVehicleTracker playerVehicleTracker = wrapper.user().get(PlayerVehicleTracker.class);
if (playerVehicleTracker.getVehicleId() != -1) {
final PacketWrapper bundleStart = wrapper.create(ClientboundPackets1_19_4.BUNDLE);
bundleStart.send(Protocol1_19_4To1_19_3.class);
final PacketWrapper setPassengers = wrapper.create(ClientboundPackets1_19_4.SET_PASSENGERS);
setPassengers.write(Type.VAR_INT, playerVehicleTracker.getVehicleId()); // vehicle id
setPassengers.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[0]); // passenger ids
setPassengers.send(Protocol1_19_4To1_19_3.class);
wrapper.send(Protocol1_19_4To1_19_3.class);
wrapper.cancel();
final PacketWrapper bundleEnd = wrapper.create(ClientboundPackets1_19_4.BUNDLE);
bundleEnd.send(Protocol1_19_4To1_19_3.class);
playerVehicleTracker.setVehicleId(-1);
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_19_3.SET_PASSENGERS, new PacketHandlers() {
@Override
protected void register() {
map(Type.VAR_INT); // vehicle id
map(Type.VAR_INT_ARRAY_PRIMITIVE); // passenger ids
handler(wrapper -> {
final PlayerVehicleTracker playerVehicleTracker = wrapper.user().get(PlayerVehicleTracker.class);
final int clientEntityId = wrapper.user().getEntityTracker(Protocol1_19_4To1_19_3.class).clientEntityId();
final int vehicleId = wrapper.get(Type.VAR_INT, 0);
if (playerVehicleTracker.getVehicleId() == vehicleId) {
playerVehicleTracker.setVehicleId(-1);
}
final int[] passengerIds = wrapper.get(Type.VAR_INT_ARRAY_PRIMITIVE, 0);
for (int passengerId : passengerIds) {
if (passengerId == clientEntityId) {
playerVehicleTracker.setVehicleId(vehicleId);
break;
}
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_19_3.ENTITY_TELEPORT, new PacketHandlers() {
@Override
protected void register() {
handler(wrapper -> {
final int entityId = wrapper.read(Type.VAR_INT); // entity id
final int clientEntityId = wrapper.user().getEntityTracker(Protocol1_19_4To1_19_3.class).clientEntityId();
if (entityId != clientEntityId) {
wrapper.write(Type.VAR_INT, entityId); // entity id
return;
}
wrapper.setPacketType(ClientboundPackets1_19_4.PLAYER_POSITION);
wrapper.passthrough(Type.DOUBLE); // x
wrapper.passthrough(Type.DOUBLE); // y
wrapper.passthrough(Type.DOUBLE); // z
wrapper.write(Type.FLOAT, wrapper.read(Type.BYTE) * 360F / 256F); // yaw
wrapper.write(Type.FLOAT, wrapper.read(Type.BYTE) * 360F / 256F); // pitch
wrapper.read(Type.BOOLEAN); // on ground
wrapper.write(Type.BYTE, (byte) 0); // flags
wrapper.write(Type.VAR_INT, -1); // teleport id
});
}
});
@@ -109,6 +179,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_3
map(Type.STRING); // Dimension
map(Type.STRING); // World
handler(worldDataTrackerHandlerByKey());
handler(wrapper -> wrapper.user().put(new PlayerVehicleTracker(wrapper.user())));
}
});
@@ -162,13 +233,20 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_3
}
meta.setMetaType(Types1_19_4.META_TYPES.byId(id));
});
registerMetaTypeHandler(Types1_19_4.META_TYPES.itemType, Types1_19_4.META_TYPES.blockStateType, Types1_19_4.META_TYPES.particleType);
registerMetaTypeHandler(Types1_19_4.META_TYPES.itemType, Types1_19_4.META_TYPES.blockStateType, Types1_19_4.META_TYPES.optionalBlockStateType, Types1_19_4.META_TYPES.particleType);
filter().filterFamily(Entity1_19_4Types.MINECART_ABSTRACT).index(11).handler((event, meta) -> {
final int blockState = meta.value();
meta.setValue(protocol.getMappingData().getNewBlockStateId(blockState));
});
filter().filterFamily(Entity1_19_4Types.BOAT).index(11).handler((event, meta) -> {
final int boatType = meta.value();
if (boatType > 4) { // Cherry added
meta.setValue(boatType + 1);
}
});
filter().filterFamily(Entity1_19_4Types.ABSTRACT_HORSE).removeIndex(18); // Owner UUID
}
@@ -181,4 +259,4 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_3
public EntityType typeFromId(final int type) {
return Entity1_19_4Types.getTypeFromId(type);
}
}
}
@@ -40,10 +40,34 @@ public final class InventoryPackets extends ItemRewriter<ClientboundPackets1_19_
blockRewriter.registerBlockAction(ClientboundPackets1_19_3.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_19_3.BLOCK_CHANGE);
blockRewriter.registerVarLongMultiBlockChange(ClientboundPackets1_19_3.MULTI_BLOCK_CHANGE);
blockRewriter.registerEffect(ClientboundPackets1_19_3.EFFECT, 1010, 2001);
blockRewriter.registerChunkData1_19(ClientboundPackets1_19_3.CHUNK_DATA, Chunk1_18Type::new);
blockRewriter.registerBlockEntityData(ClientboundPackets1_19_3.BLOCK_ENTITY_DATA);
protocol.registerClientbound(ClientboundPackets1_19_3.EFFECT, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // Effect Id
map(Type.POSITION1_14); // Location
map(Type.INT); // Data
handler(wrapper -> {
int id = wrapper.get(Type.INT, 0);
int data = wrapper.get(Type.INT, 1);
if (id == 1010) { // Play record
if (data >= 1092 && data <= 1106) {
// These IDs are valid records
wrapper.set(Type.INT, 1, protocol.getMappingData().getNewItemId(data));
} else {
// Send stop record instead
wrapper.set(Type.INT, 0, 1011);
wrapper.set(Type.INT, 1, 0);
}
} else if (id == 2001) { // Block break + block break sound
wrapper.set(Type.INT, 1, protocol.getMappingData().getNewBlockStateId(data));
}
});
}
});
protocol.registerClientbound(ClientboundPackets1_19_3.OPEN_WINDOW, new PacketHandlers() {
@Override
public void register() {
@@ -30,11 +30,8 @@ public class RecipeRewriter1_19_4<C extends ClientboundPacketType> extends Recip
}
@Override
public void handleCraftingShapeless(final PacketWrapper wrapper) throws Exception {
wrapper.passthrough(Type.STRING); // Group
wrapper.passthrough(Type.VAR_INT); // Crafting book category
handleIngredients(wrapper);
rewrite(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Result
public void handleCraftingShaped(final PacketWrapper wrapper) throws Exception {
super.handleCraftingShaped(wrapper);
wrapper.passthrough(Type.BOOLEAN); // Show notification
}
}
@@ -0,0 +1,39 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 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.viaversion.protocols.protocol1_19_4to1_19_3.storage;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
public class PlayerVehicleTracker extends StoredObject {
private int vehicleId = -1;
public PlayerVehicleTracker(final UserConnection user) {
super(user);
}
public int getVehicleId() {
return this.vehicleId;
}
public void setVehicleId(final int vehicleId) {
this.vehicleId = vehicleId;
}
}
@@ -30,10 +30,9 @@ import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_19;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.libs.kyori.adventure.text.Component;
import com.viaversion.viaversion.libs.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
import com.viaversion.viaversion.protocols.base.ServerboundLoginPackets;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ChatRewriter;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.ServerboundPackets1_17;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.ClientboundPackets1_18;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.data.MappingData;
@@ -124,7 +123,7 @@ public final class Protocol1_19To1_18_2 extends AbstractProtocol<ClientboundPack
if (!isTextComponentNull(component)) {
wrapper.write(Type.COMPONENT, component);
} else {
wrapper.write(Type.COMPONENT, GsonComponentSerializer.gson().serializeToTree(Component.empty()));
wrapper.write(Type.COMPONENT, ChatRewriter.emptyComponent());
}
};
registerClientbound(ClientboundPackets1_18.TITLE_TEXT, titleHandler);
@@ -276,7 +275,7 @@ public final class Protocol1_19To1_18_2 extends AbstractProtocol<ClientboundPack
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
.reader("item", ParticleType.Readers.VAR_INT_ITEM)
.reader("vibration", ParticleType.Readers.VIBRATION)
.reader("vibration", ParticleType.Readers.VIBRATION1_19)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK);
Entity1_19Types.initialize(this);
@@ -40,8 +40,7 @@ public final class MappingData extends MappingDataBase {
@Override
protected void loadExtras(final CompoundTag daata) {
try {
// TODO Read uncompressed file
final ListTag chatTypes = BinaryTagIO.readCompressedInputStream(MappingDataLoader.getResource("chat-types-1.19.nbt")).get("values");
final ListTag chatTypes = BinaryTagIO.readInputStream(MappingDataLoader.getResource("chat-types-1.19.nbt")).get("values");
for (final Tag chatType : chatTypes) {
final CompoundTag chatTypeCompound = (CompoundTag) chatType;
final NumberTag idTag = chatTypeCompound.get("id");
@@ -24,15 +24,18 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.google.common.collect.Maps;
import com.google.gson.JsonElement;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.data.entity.DimensionData;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_19Types;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.minecraft.metadata.MetaType;
import com.viaversion.viaversion.api.minecraft.metadata.Metadata;
import com.viaversion.viaversion.api.minecraft.nbt.BinaryTagIO;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.Particle;
import com.viaversion.viaversion.api.type.types.version.Types1_18;
import com.viaversion.viaversion.api.type.types.version.Types1_19;
import com.viaversion.viaversion.data.entity.DimensionDataImpl;
@@ -41,6 +44,7 @@ import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ClientboundPacke
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.Protocol1_19To1_18_2;
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.storage.DimensionRegistryStorage;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.util.Key;
import com.viaversion.viaversion.util.Pair;
import java.io.IOException;
import java.util.ArrayList;
@@ -353,9 +357,29 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_18,
@Override
protected void registerRewrites() {
filter().handler((event, meta) -> meta.setMetaType(Types1_19.META_TYPES.byId(meta.metaType().typeId())));
filter().handler((event, meta) -> {
meta.setMetaType(Types1_19.META_TYPES.byId(meta.metaType().typeId()));
registerMetaTypeHandler(Types1_19.META_TYPES.itemType, Types1_19.META_TYPES.blockStateType, Types1_19.META_TYPES.particleType);
final MetaType type = meta.metaType();
if (type == Types1_19.META_TYPES.particleType) {
final Particle particle = (Particle) meta.getValue();
final ParticleMappings particleMappings = protocol.getMappingData().getParticleMappings();
if (particle.getId() == particleMappings.id("vibration")) {
// Remove the position
particle.getArguments().remove(0);
final String resourceLocation = Key.stripMinecraftNamespace(particle.getArguments().get(0).get());
if (resourceLocation.equals("entity")) {
// Add Y offset
particle.getArguments().add(2, new Particle.ParticleData(Type.FLOAT, 0F));
}
}
rewriteParticle(particle);
}
});
registerMetaTypeHandler(Types1_19.META_TYPES.itemType, Types1_19.META_TYPES.blockStateType, null, null);
filter().filterFamily(Entity1_19Types.MINECART_ABSTRACT).index(11).handler((event, meta) -> {
// Convert to new block id
@@ -18,6 +18,7 @@
package com.viaversion.viaversion.protocols.protocol1_19to1_18_2.packets;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.data.ParticleMappings;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
@@ -27,6 +28,7 @@ import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.ServerboundPacke
import com.viaversion.viaversion.protocols.protocol1_19to1_18_2.provider.AckSequenceProvider;
import com.viaversion.viaversion.rewriter.ItemRewriter;
import com.viaversion.viaversion.rewriter.RecipeRewriter;
import com.viaversion.viaversion.util.Key;
public final class InventoryPackets extends ItemRewriter<ClientboundPackets1_18, ServerboundPackets1_19, Protocol1_19To1_18_2> {
@@ -54,6 +56,19 @@ public final class InventoryPackets extends ItemRewriter<ClientboundPackets1_18,
map(Type.FLOAT); // 7 - Offset Z
map(Type.FLOAT); // 8 - Particle Data
map(Type.INT); // 9 - Particle Count
handler(wrapper -> {
final int id = wrapper.get(Type.VAR_INT, 0);
final ParticleMappings particleMappings = protocol.getMappingData().getParticleMappings();
if (id == particleMappings.id("vibration")) {
wrapper.read(Type.POSITION1_14); // Remove position
final String resourceLocation = Key.stripMinecraftNamespace(wrapper.passthrough(Type.STRING));
if (resourceLocation.equals("entity")) {
wrapper.passthrough(Type.VAR_INT); // Target entity
wrapper.write(Type.FLOAT, 0F); // Y offset
}
}
});
handler(getSpawnParticleHandler(Type.VAR_INT, Type.FLAT_VAR_INT_ITEM));
}
});
@@ -0,0 +1,104 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 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.viaversion.protocols.protocol1_20to1_19_4;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
import com.viaversion.viaversion.api.data.MappingDataBase;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_19_4Types;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.minecraft.ParticleType;
import com.viaversion.viaversion.api.type.types.version.Types1_20;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ServerboundPackets1_19_4;
import com.viaversion.viaversion.protocols.protocol1_20to1_19_4.packets.EntityPackets;
import com.viaversion.viaversion.protocols.protocol1_20to1_19_4.packets.InventoryPackets;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
public final class Protocol1_20To1_19_4 extends AbstractProtocol<ClientboundPackets1_19_4, ClientboundPackets1_19_4, ServerboundPackets1_19_4, ServerboundPackets1_19_4> {
public static final MappingData MAPPINGS = new MappingDataBase("1.19.4", "1.20");
private final EntityPackets entityRewriter = new EntityPackets(this);
private final InventoryPackets itemRewriter = new InventoryPackets(this);
public Protocol1_20To1_19_4() {
super(ClientboundPackets1_19_4.class, ClientboundPackets1_19_4.class, ServerboundPackets1_19_4.class, ServerboundPackets1_19_4.class);
}
@Override
protected void registerPackets() {
super.registerPackets();
final TagRewriter<ClientboundPackets1_19_4> tagRewriter = new TagRewriter<>(this);
tagRewriter.registerGeneric(ClientboundPackets1_19_4.TAGS);
final SoundRewriter<ClientboundPackets1_19_4> soundRewriter = new SoundRewriter<>(this);
soundRewriter.register1_19_3Sound(ClientboundPackets1_19_4.SOUND);
soundRewriter.registerSound(ClientboundPackets1_19_4.ENTITY_SOUND);
new StatisticsRewriter<>(this).register(ClientboundPackets1_19_4.STATISTICS);
registerClientbound(ClientboundPackets1_19_4.COMBAT_END, wrapper -> {
wrapper.passthrough(Type.VAR_INT); // Duration
wrapper.read(Type.INT); // Killer ID
});
registerClientbound(ClientboundPackets1_19_4.COMBAT_KILL, wrapper -> {
wrapper.passthrough(Type.VAR_INT); // Duration
wrapper.read(Type.INT); // Killer ID
});
}
@Override
protected void onMappingDataLoaded() {
super.onMappingDataLoaded();
Types1_20.PARTICLE.filler(this)
.reader("block", ParticleType.Readers.BLOCK)
.reader("block_marker", ParticleType.Readers.BLOCK)
.reader("dust", ParticleType.Readers.DUST)
.reader("falling_dust", ParticleType.Readers.BLOCK)
.reader("dust_color_transition", ParticleType.Readers.DUST_TRANSITION)
.reader("item", ParticleType.Readers.VAR_INT_ITEM)
.reader("vibration", ParticleType.Readers.VIBRATION1_19)
.reader("sculk_charge", ParticleType.Readers.SCULK_CHARGE)
.reader("shriek", ParticleType.Readers.SHRIEK);
}
@Override
public void init(final UserConnection user) {
addEntityTracker(user, new EntityTrackerBase(user, Entity1_19_4Types.PLAYER));
}
@Override
public MappingData getMappingData() {
return MAPPINGS;
}
@Override
public EntityPackets getEntityRewriter() {
return entityRewriter;
}
@Override
public InventoryPackets getItemRewriter() {
return itemRewriter;
}
}
@@ -0,0 +1,140 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 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.viaversion.protocols.protocol1_20to1_19_4.packets;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.FloatTag;
import com.github.steveice10.opennbt.tag.builtin.IntTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_19_4Types;
import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_19_4;
import com.viaversion.viaversion.api.type.types.version.Types1_20;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4;
import com.viaversion.viaversion.protocols.protocol1_20to1_19_4.Protocol1_20To1_19_4;
import com.viaversion.viaversion.rewriter.EntityRewriter;
public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_4, Protocol1_20To1_19_4> {
public EntityPackets(final Protocol1_20To1_19_4 protocol) {
super(protocol);
}
@Override
public void registerPackets() {
registerTrackerWithData1_19(ClientboundPackets1_19_4.SPAWN_ENTITY, Entity1_19_4Types.FALLING_BLOCK);
registerMetadataRewriter(ClientboundPackets1_19_4.ENTITY_METADATA, Types1_19_4.METADATA_LIST, Types1_20.METADATA_LIST);
registerRemoveEntities(ClientboundPackets1_19_4.REMOVE_ENTITIES);
protocol.registerClientbound(ClientboundPackets1_19_4.JOIN_GAME, new PacketHandlers() {
@Override
public void register() {
map(Type.INT); // Entity id
map(Type.BOOLEAN); // Hardcore
map(Type.UNSIGNED_BYTE); // Gamemode
map(Type.BYTE); // Previous Gamemode
map(Type.STRING_ARRAY); // World List
map(Type.NBT); // Dimension registry
map(Type.STRING); // Dimension key
map(Type.STRING); // World
map(Type.LONG); // Seed
map(Type.VAR_INT); // Max players
map(Type.VAR_INT); // Chunk radius
map(Type.VAR_INT); // Simulation distance
map(Type.BOOLEAN); // Reduced debug info
map(Type.BOOLEAN); // Show death screen
map(Type.BOOLEAN); // Debug
map(Type.BOOLEAN); // Flat
map(Type.OPTIONAL_GLOBAL_POSITION); // Last death location
create(Type.VAR_INT, 0); // Portal cooldown
handler(dimensionDataHandler()); // Caches dimensions to access data like height later
handler(biomeSizeTracker()); // Tracks the amount of biomes sent for chunk data
handler(worldDataTrackerHandlerByKey()); // Tracks world height and name for chunk data and entity (un)tracking
handler(wrapper -> {
final CompoundTag registry = wrapper.get(Type.NBT, 0);
final CompoundTag damageTypeRegistry = registry.get("minecraft:damage_type");
final ListTag damageTypes = damageTypeRegistry.get("value");
int highestId = -1;
for (final Tag damageType : damageTypes) {
final IntTag id = ((CompoundTag) damageType).get("id");
highestId = Math.max(highestId, id.asInt());
}
// AaaaAAAaa
final CompoundTag outsideBorderReason = new CompoundTag();
final CompoundTag outsideBorderElement = new CompoundTag();
outsideBorderElement.put("scaling", new StringTag("always"));
outsideBorderElement.put("exhaustion", new FloatTag(0F));
outsideBorderElement.put("message_id", new StringTag("badRespawnPoint"));
outsideBorderReason.put("id", new IntTag(highestId + 1));
outsideBorderReason.put("name", new StringTag("minecraft:outside_border"));
outsideBorderReason.put("element", outsideBorderElement);
damageTypes.add(outsideBorderReason);
final CompoundTag genericKillReason = new CompoundTag();
final CompoundTag genericKillElement = new CompoundTag();
genericKillElement.put("scaling", new StringTag("always"));
genericKillElement.put("exhaustion", new FloatTag(0F));
genericKillElement.put("message_id", new StringTag("badRespawnPoint"));
genericKillReason.put("id", new IntTag(highestId + 2));
genericKillReason.put("name", new StringTag("minecraft:generic_kill"));
genericKillReason.put("element", genericKillElement);
damageTypes.add(genericKillReason);
});
}
});
protocol.registerClientbound(ClientboundPackets1_19_4.RESPAWN, new PacketHandlers() {
@Override
public void register() {
map(Type.STRING); // Dimension
map(Type.STRING); // World
map(Type.LONG); // Seed
map(Type.UNSIGNED_BYTE); // Gamemode
map(Type.BYTE); // Previous gamemode
map(Type.BOOLEAN); // Debug
map(Type.BOOLEAN); // Flat
map(Type.BYTE); // Data to keep
map(Type.OPTIONAL_GLOBAL_POSITION); // Last death location
create(Type.VAR_INT, 0); // Portal cooldown
handler(worldDataTrackerHandlerByKey()); // Tracks world height and name for chunk data and entity (un)tracking
}
});
}
@Override
protected void registerRewrites() {
filter().handler((event, meta) -> meta.setMetaType(Types1_20.META_TYPES.byId(meta.metaType().typeId())));
registerMetaTypeHandler(Types1_20.META_TYPES.itemType, Types1_20.META_TYPES.blockStateType, Types1_20.META_TYPES.optionalBlockStateType, Types1_20.META_TYPES.particleType);
filter().filterFamily(Entity1_19_4Types.MINECART_ABSTRACT).index(11).handler((event, meta) -> {
final int blockState = meta.value();
meta.setValue(protocol.getMappingData().getNewBlockStateId(blockState));
});
}
@Override
public EntityType typeFromId(final int type) {
return Entity1_19_4Types.getTypeFromId(type);
}
}
@@ -0,0 +1,197 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2023 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.viaversion.protocols.protocol1_20to1_19_4.packets;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ChatRewriter;
import com.viaversion.viaversion.protocols.protocol1_18to1_17_1.types.Chunk1_18Type;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ClientboundPackets1_19_4;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.ServerboundPackets1_19_4;
import com.viaversion.viaversion.protocols.protocol1_19_4to1_19_3.rewriter.RecipeRewriter1_19_4;
import com.viaversion.viaversion.protocols.protocol1_20to1_19_4.Protocol1_20To1_19_4;
import com.viaversion.viaversion.rewriter.BlockRewriter;
import com.viaversion.viaversion.rewriter.ItemRewriter;
import com.viaversion.viaversion.rewriter.RecipeRewriter;
import com.viaversion.viaversion.util.Key;
public final class InventoryPackets extends ItemRewriter<ClientboundPackets1_19_4, ServerboundPackets1_19_4, Protocol1_20To1_19_4> {
public InventoryPackets(final Protocol1_20To1_19_4 protocol) {
super(protocol);
}
@Override
public void registerPackets() {
final BlockRewriter<ClientboundPackets1_19_4> blockRewriter = new BlockRewriter<>(protocol, Type.POSITION1_14);
blockRewriter.registerBlockAction(ClientboundPackets1_19_4.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_19_4.BLOCK_CHANGE);
blockRewriter.registerEffect(ClientboundPackets1_19_4.EFFECT, 1010, 2001);
blockRewriter.registerBlockEntityData(ClientboundPackets1_19_4.BLOCK_ENTITY_DATA, this::handleBlockEntity);
registerOpenWindow(ClientboundPackets1_19_4.OPEN_WINDOW);
registerSetCooldown(ClientboundPackets1_19_4.COOLDOWN);
registerWindowItems1_17_1(ClientboundPackets1_19_4.WINDOW_ITEMS);
registerSetSlot1_17_1(ClientboundPackets1_19_4.SET_SLOT);
registerEntityEquipmentArray(ClientboundPackets1_19_4.ENTITY_EQUIPMENT);
registerClickWindow1_17_1(ServerboundPackets1_19_4.CLICK_WINDOW);
registerTradeList1_19(ClientboundPackets1_19_4.TRADE_LIST);
registerCreativeInvAction(ServerboundPackets1_19_4.CREATIVE_INVENTORY_ACTION, Type.FLAT_VAR_INT_ITEM);
registerWindowPropertyEnchantmentHandler(ClientboundPackets1_19_4.WINDOW_PROPERTY);
registerSpawnParticle1_19(ClientboundPackets1_19_4.SPAWN_PARTICLE);
protocol.registerClientbound(ClientboundPackets1_19_4.ADVANCEMENTS, wrapper -> {
wrapper.passthrough(Type.BOOLEAN); // Reset/clear
int size = wrapper.passthrough(Type.VAR_INT); // Mapping size
for (int i = 0; i < size; i++) {
wrapper.passthrough(Type.STRING); // Identifier
// Parent
if (wrapper.passthrough(Type.BOOLEAN))
wrapper.passthrough(Type.STRING);
// Display data
if (wrapper.passthrough(Type.BOOLEAN)) {
wrapper.passthrough(Type.COMPONENT); // Title
wrapper.passthrough(Type.COMPONENT); // Description
handleItemToClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)); // Icon
wrapper.passthrough(Type.VAR_INT); // Frame type
int flags = wrapper.passthrough(Type.INT); // Flags
if ((flags & 1) != 0) {
wrapper.passthrough(Type.STRING); // Background texture
}
wrapper.passthrough(Type.FLOAT); // X
wrapper.passthrough(Type.FLOAT); // Y
}
wrapper.passthrough(Type.STRING_ARRAY); // Criteria
int arrayLength = wrapper.passthrough(Type.VAR_INT);
for (int array = 0; array < arrayLength; array++) {
wrapper.passthrough(Type.STRING_ARRAY); // String array
}
wrapper.write(Type.BOOLEAN, false); // Sends telemetry
}
});
protocol.registerClientbound(ClientboundPackets1_19_4.OPEN_SIGN_EDITOR, wrapper -> {
wrapper.passthrough(Type.POSITION1_14);
wrapper.write(Type.BOOLEAN, true); // Front text
});
protocol.registerServerbound(ServerboundPackets1_19_4.UPDATE_SIGN, wrapper -> {
wrapper.passthrough(Type.POSITION1_14);
final boolean frontText = wrapper.read(Type.BOOLEAN);
if (!frontText) {
wrapper.cancel();
}
});
protocol.registerClientbound(ClientboundPackets1_19_4.CHUNK_DATA, new PacketHandlers() {
@Override
protected void register() {
handler(blockRewriter.chunkDataHandler1_19(Chunk1_18Type::new, InventoryPackets.this::handleBlockEntity));
read(Type.BOOLEAN); // Trust edges
}
});
protocol.registerClientbound(ClientboundPackets1_19_4.UPDATE_LIGHT, wrapper -> {
wrapper.passthrough(Type.VAR_INT); // X
wrapper.passthrough(Type.VAR_INT); // Y
wrapper.read(Type.BOOLEAN); // Trust edges
});
protocol.registerClientbound(ClientboundPackets1_19_4.MULTI_BLOCK_CHANGE, new PacketHandlers() {
@Override
public void register() {
map(Type.LONG); // Chunk position
read(Type.BOOLEAN); // Suppress light updates
handler(wrapper -> {
for (final BlockChangeRecord record : wrapper.passthrough(Type.VAR_LONG_BLOCK_CHANGE_RECORD_ARRAY)) {
record.setBlockId(protocol.getMappingData().getNewBlockStateId(record.getBlockId()));
}
});
}
});
final RecipeRewriter<ClientboundPackets1_19_4> recipeRewriter = new RecipeRewriter1_19_4<>(protocol);
protocol.registerClientbound(ClientboundPackets1_19_4.DECLARE_RECIPES, wrapper -> {
final int size = wrapper.passthrough(Type.VAR_INT);
int newSize = size;
for (int i = 0; i < size; i++) {
final String type = wrapper.read(Type.STRING);
final String cutType = Key.stripMinecraftNamespace(type);
if (cutType.equals("smithing")) {
newSize--;
wrapper.read(Type.STRING); // Recipe identifier
wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT); // Base
wrapper.read(Type.FLAT_VAR_INT_ITEM_ARRAY_VAR_INT); // Additions
wrapper.read(Type.FLAT_VAR_INT_ITEM); // Result
continue;
}
wrapper.write(Type.STRING, type);
wrapper.passthrough(Type.STRING); // Recipe Identifier
recipeRewriter.handleRecipeType(wrapper, cutType);
}
wrapper.set(Type.VAR_INT, 0, newSize);
});
}
private void handleBlockEntity(final BlockEntity blockEntity) {
// Check for signs
if (blockEntity.typeId() != 7 && blockEntity.typeId() != 8) {
return;
}
final CompoundTag tag = blockEntity.tag();
final CompoundTag frontText = new CompoundTag();
tag.put("front_text", frontText);
final ListTag messages = new ListTag(StringTag.class);
for (int i = 1; i < 5; i++) {
final Tag text = tag.get("Text" + i);
messages.add(text != null ? text : new StringTag(ChatRewriter.emptyComponentString()));
}
frontText.put("messages", messages);
final ListTag filteredMessages = new ListTag(StringTag.class);
for (int i = 1; i < 5; i++) {
final Tag text = tag.get("FilteredText" + i);
filteredMessages.add(text != null ? text : new StringTag(ChatRewriter.emptyComponentString()));
}
frontText.put("filtered_messages", filteredMessages);
final Tag color = tag.remove("Color");
if (color != null) {
frontText.put("color", color);
}
final Tag glowing = tag.remove("GlowingText");
if (glowing != null) {
frontText.put("has_glowing_text", glowing);
}
}
}
@@ -31,8 +31,6 @@ public class Protocol1_9To1_9_1 extends AbstractProtocol<ClientboundPackets1_9,
@Override
protected void registerPackets() {
// Currently supports 1.9.1 and 1.9.2
registerClientbound(ClientboundPackets1_9.JOIN_GAME, new PacketHandlers() {
@Override
public void register() {
@@ -17,22 +17,27 @@
*/
package com.viaversion.viaversion.rewriter;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.api.data.Mappings;
import com.viaversion.viaversion.api.data.entity.EntityTracker;
import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntity;
import com.viaversion.viaversion.api.minecraft.blockentity.BlockEntityImpl;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.util.MathUtil;
import java.util.List;
import java.util.function.Consumer;
import org.checkerframework.checker.nullness.qual.Nullable;
public class BlockRewriter<C extends ClientboundPacketType> {
private final Protocol<C, ?, ?, ?> protocol;
@@ -111,6 +116,20 @@ public class BlockRewriter<C extends ClientboundPacketType> {
});
}
public void registerVarLongMultiBlockChange1_20(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Type.LONG); // Chunk position
handler(wrapper -> {
for (BlockChangeRecord record : wrapper.passthrough(Type.VAR_LONG_BLOCK_CHANGE_RECORD_ARRAY)) {
record.setBlockId(protocol.getMappingData().getNewBlockStateId(record.getBlockId()));
}
});
}
});
}
public void registerAcknowledgePlayerDigging(C packetType) {
// Same exact handler
registerBlockChange(packetType);
@@ -137,7 +156,15 @@ public class BlockRewriter<C extends ClientboundPacketType> {
}
public void registerChunkData1_19(C packetType, ChunkTypeSupplier chunkTypeSupplier) {
protocol.registerClientbound(packetType, wrapper -> {
registerChunkData1_19(packetType, chunkTypeSupplier, null);
}
public void registerChunkData1_19(C packetType, ChunkTypeSupplier chunkTypeSupplier, @Nullable Consumer<BlockEntity> blockEntityHandler) {
protocol.registerClientbound(packetType, chunkDataHandler1_19(chunkTypeSupplier, blockEntityHandler));
}
public PacketHandler chunkDataHandler1_19(ChunkTypeSupplier chunkTypeSupplier, @Nullable Consumer<BlockEntity> blockEntityHandler) {
return wrapper -> {
final EntityTracker tracker = protocol.getEntityRewriter().tracker(wrapper.user());
Preconditions.checkArgument(tracker.biomesSent() != 0, "Biome count not set");
Preconditions.checkArgument(tracker.currentWorldSectionHeight() != 0, "Section height not set");
@@ -154,28 +181,42 @@ public class BlockRewriter<C extends ClientboundPacketType> {
}
final Mappings blockEntityMappings = protocol.getMappingData().getBlockEntityMappings();
if (blockEntityMappings != null) {
if (blockEntityMappings != null || blockEntityHandler != null) {
List<BlockEntity> blockEntities = chunk.blockEntities();
for (int i = 0; i < blockEntities.size(); i++) {
final BlockEntity blockEntity = blockEntities.get(i);
blockEntities.set(i, blockEntity.withTypeId(protocol.getMappingData().getBlockEntityMappings().getNewIdOrDefault(blockEntity.typeId(), blockEntity.typeId())));
if (blockEntityMappings != null) {
blockEntities.set(i, blockEntity.withTypeId(blockEntityMappings.getNewIdOrDefault(blockEntity.typeId(), blockEntity.typeId())));
}
if (blockEntityHandler != null && blockEntity.tag() != null) {
blockEntityHandler.accept(blockEntity);
}
}
}
});
};
}
public void registerBlockEntityData(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Type.POSITION1_14);
handler(wrapper -> {
final Mappings mappings = protocol.getMappingData().getBlockEntityMappings();
if (mappings != null) {
final int blockEntityId = wrapper.read(Type.VAR_INT);
wrapper.write(Type.VAR_INT, mappings.getNewIdOrDefault(blockEntityId, blockEntityId));
}
});
registerBlockEntityData(packetType, null);
}
public void registerBlockEntityData(C packetType, @Nullable Consumer<BlockEntity> blockEntityHandler) {
protocol.registerClientbound(packetType, wrapper -> {
final Position position = wrapper.passthrough(Type.POSITION1_14);
final int blockEntityId = wrapper.read(Type.VAR_INT);
final Mappings mappings = protocol.getMappingData().getBlockEntityMappings();
if (mappings != null) {
wrapper.write(Type.VAR_INT, mappings.getNewIdOrDefault(blockEntityId, blockEntityId));
} else {
wrapper.write(Type.VAR_INT, blockEntityId);
}
final CompoundTag tag;
if (blockEntityHandler != null && (tag = wrapper.passthrough(Type.NBT)) != null) {
final BlockEntity blockEntity = new BlockEntityImpl(BlockEntity.pack(position.x(), position.z()), (short) position.y(), blockEntityId, tag);
blockEntityHandler.accept(blockEntity);
}
});
}
@@ -234,18 +234,25 @@ public abstract class EntityRewriter<C extends ClientboundPacketType, T extends
/**
* Registers a metadata handler to rewrite, item, block, and particle ids stored in metadata.
*
* @param itemType item meta type if needed
* @param blockType block meta type if needed
* @param particleType particle meta type if needed
* @param itemType item meta type if needed
* @param blockStateType block state meta type if needed
* @param optionalBlockStateType optional block state meta type if needed
* @param particleType particle meta type if needed
*/
public void registerMetaTypeHandler(@Nullable MetaType itemType, @Nullable MetaType blockType, @Nullable MetaType particleType) {
public void registerMetaTypeHandler(@Nullable MetaType itemType, @Nullable MetaType blockStateType, @Nullable MetaType optionalBlockStateType, @Nullable MetaType particleType) {
filter().handler((event, meta) -> {
if (itemType != null && meta.metaType() == itemType) {
final MetaType type = meta.metaType();
if (type == itemType) {
protocol.getItemRewriter().handleItemToClient(meta.value());
} else if (blockType != null && meta.metaType() == blockType) {
} else if (type == blockStateType) {
int data = meta.value();
meta.setValue(protocol.getMappingData().getNewBlockStateId(data));
} else if (particleType != null && meta.metaType() == particleType) {
} else if (type == optionalBlockStateType) {
int data = meta.value();
if (data != 0) {
meta.setValue(protocol.getMappingData().getNewBlockStateId(data));
}
} else if (type == particleType) {
rewriteParticle(meta.value());
}
});
@@ -85,6 +85,25 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
});
}
public void registerOpenWindow(C packetType) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
public void register() {
map(Type.VAR_INT); // Container id
handler(wrapper -> {
final int windowType = wrapper.read(Type.VAR_INT);
final int mappedId = protocol.getMappingData().getMenuMappings().getNewId(windowType);
if (mappedId == -1) {
wrapper.cancel();
return;
}
wrapper.write(Type.VAR_INT, mappedId);
});
}
});
}
public void registerSetSlot(C packetType, Type<Item> type) {
protocol.registerClientbound(packetType, new PacketHandlers() {
@Override
@@ -352,7 +371,9 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
public PacketHandler getSpawnParticleHandler(Type<Integer> idType, Type<Item> itemType) {
return wrapper -> {
int id = wrapper.get(idType, 0);
if (id == -1) return;
if (id == -1) {
return;
}
ParticleMappings mappings = protocol.getMappingData().getParticleMappings();
if (mappings.isBlockParticle(id)) {
@@ -362,9 +383,9 @@ public abstract class ItemRewriter<C extends ClientboundPacketType, S extends Se
handleItemToClient(wrapper.passthrough(itemType));
}
int newId = protocol.getMappingData().getNewParticleId(id);
if (newId != id) {
wrapper.set(idType, 0, newId);
int mappedId = protocol.getMappingData().getNewParticleId(id);
if (mappedId != id) {
wrapper.set(idType, 0, mappedId);
}
};
}
@@ -29,7 +29,7 @@ public final class TaskScheduler implements Scheduler {
private final ExecutorService executorService = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("Via Async Task %d").build());
private final ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(
0,
1, // Fix for https://bugs.openjdk.java.net/browse/JDK-8129861
new ThreadFactoryBuilder().setNameFormat("Via Async Scheduler %d").build()
);
@@ -23,6 +23,7 @@ import com.viaversion.viaversion.api.platform.UnsupportedSoftware;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class UnsupportedPlugin implements UnsupportedSoftware {
@@ -50,13 +51,13 @@ public final class UnsupportedPlugin implements UnsupportedSoftware {
}
@Override
public final boolean findMatch() {
public final @Nullable String match() {
for (final String identifier : identifiers) {
if (Via.getPlatform().hasPlugin(identifier)) {
return true;
return identifier;
}
}
return false;
return null;
}
public static final class Builder {
@@ -24,6 +24,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class UnsupportedServerSoftware implements UnsupportedSoftware {
@@ -53,20 +54,20 @@ public final class UnsupportedServerSoftware implements UnsupportedSoftware {
}
@Override
public final boolean findMatch() {
public final @Nullable String match() {
for (String className : classNames) {
try {
Class.forName(className);
return true;
return name;
} catch (ClassNotFoundException ignored) {
}
}
for (UnsupportedMethods method : methods) {
if (method.findMatch()) {
return true;
return name;
}
}
return false;
return null;
}
public static final class Builder {
@@ -2752,5 +2752,70 @@
"advancements.story.smelt_iron.title": null,
"advancements.story.smelt_iron.description": null,
"advancements.story.upgrade_tools.title": null,
"advancements.story.upgrade_tools.description": null
"selectWorld.edit.openFolder": null,
"selectWorld.edit.save": null,
"selectWorld.versionWarning": null,
"selectWorld.versionJoinButton": null,
"selectWorld.allowCommands.info": null,
"multiplayer.downloadingTerrain": null,
"multiplayer.disconnect.banned": null,
"multiplayer.disconnect.ip_banned": null,
"multiplayer.disconnect.kicked": null,
"disconnect.loginFailed": null,
"disconnect.loginFailedInfo": null,
"options.narrator.off": null,
"key.mouse.left": null,
"key.mouse.middle": null,
"key.mouse.right": null,
"structure_block.size_failure": null,
"death.attack.hotFloor": null,
"commands.setidletimeout.success": null,
"commands.summon.failed": null,
"commands.setblock.failed": null,
"commands.fill.success": null,
"commands.fill.failed": null,
"commands.clone.success": null,
"commands.clone.failed": null,
"commands.time.query": null,
"commands.op.success": null,
"commands.deop.success": null,
"commands.banip.invalid": null,
"commands.save.enabled": null,
"commands.save.disabled": null,
"commands.save.success": null,
"commands.advancement.criterionNotFound": null,
"commands.reload.success": null,
"commands.scoreboard.objectives.add.success": null,
"commands.scoreboard.objectives.remove.success": null,
"commands.scoreboard.objectives.list.empty": null,
"commands.scoreboard.players.list.empty": null,
"commands.defaultgamemode.success": null,
"commands.difficulty.success": null,
"commands.setworldspawn.success": null,
"commands.worldborder.center.success": null,
"commands.locate.success": null,
"subtitles.entity.generic.small_fall": null,
"subtitles.entity.llama.angry": null,
"subtitles.item.armor.equip": null,
"subtitles.item.armor.equip_elytra": null,
"debug.reload_chunks.help": null,
"debug.show_hitboxes.help": null,
"debug.clear_chat.help": null,
"debug.cycle_renderdistance.help": null,
"debug.chunk_boundaries.help": null,
"debug.advanced_tooltips.help": null,
"debug.creative_spectator.help": null,
"debug.pause_focus.help": null,
"debug.help.help": null,
"debug.reload_resourcepacks.help": null,
"advancements.adventure.sleep_in_bed.title": null,
"advancements.adventure.sniper_duel.title": null,
"advancements.adventure.sniper_duel.description": null,
"advancements.end.elytra.description": null,
"advancements.end.respawn_dragon.description": null,
"advancements.nether.get_wither_skull.description": null,
"advancements.nether.fast_travel.description": null,
"advancements.nether.uneasy_alliance.description": null,
"advancements.story.cure_zombie_villager.description": null,
"advancements.story.follow_ender_eye.description": null
}
+1 -1
View File
@@ -1,5 +1,5 @@
# Project properties - we put these here so they can be modified without causing a recompile of the build scripts
projectVersion=4.6.1
projectVersion=4.7.0
# Gradle properties
org.gradle.daemon=true
+4 -4
View File
@@ -2,9 +2,9 @@ metadata.format.version = "1.1"
[versions]
adventure = "4.12.0"
adventure = "4.13.1"
gson = "2.10.1"
fastutil = "8.5.11"
fastutil = "8.5.12"
flare = "2.0.1"
openNBT = "2.1.2"
@@ -14,8 +14,8 @@ guava = "17.0"
snakeYaml = "1.18"
snakeYaml2 = "2.0"
junit = "5.9.2"
checkerQual = "3.29.0"
junit = "5.9.3"
checkerQual = "3.34.0"
# Platforms
paper = "1.16.5-R0.1-SNAPSHOT"
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+4 -3
View File
@@ -85,9 +85,6 @@ done
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -197,6 +194,10 @@ if "$cygwin" || "$msys" ; then
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
@@ -29,16 +29,18 @@ import it.unimi.dsi.fastutil.ints.IntLinkedOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSortedSet;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.jetbrains.annotations.Nullable;
public class VelocityViaInjector implements ViaInjector {
public static Method getPlayerInfoForwardingMode;
public static final Method GET_PLAYER_INFO_FORWARDING_MODE = getPlayerInfoForwardingModeMethod();
static {
private static @Nullable Method getPlayerInfoForwardingModeMethod() {
try {
getPlayerInfoForwardingMode = Class.forName("com.velocitypowered.proxy.config.VelocityConfiguration").getMethod("getPlayerInfoForwardingMode");
return Class.forName("com.velocitypowered.proxy.config.VelocityConfiguration").getMethod("getPlayerInfoForwardingMode");
} catch (NoSuchMethodException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
@@ -95,8 +97,8 @@ public class VelocityViaInjector implements ViaInjector {
public static int getLowestSupportedProtocolVersion() {
try {
if (getPlayerInfoForwardingMode != null
&& ((Enum<?>) getPlayerInfoForwardingMode.invoke(VelocityPlugin.PROXY.getConfiguration()))
if (GET_PLAYER_INFO_FORWARDING_MODE != null
&& ((Enum<?>) GET_PLAYER_INFO_FORWARDING_MODE.invoke(VelocityPlugin.PROXY.getConfiguration()))
.name().equals("MODERN")) {
return ProtocolVersion.v1_13.getVersion();
}
@@ -28,15 +28,17 @@ import io.netty.channel.ChannelHandler;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.stream.IntStream;
import org.jetbrains.annotations.Nullable;
public class VelocityVersionProvider extends BaseVersionProvider {
private static Method getAssociation;
private static final Method GET_ASSOCIATION = getAssociationMethod();
static {
private static @Nullable Method getAssociationMethod() {
try {
getAssociation = Class.forName("com.velocitypowered.proxy.connection.MinecraftConnection").getMethod("getAssociation");
return Class.forName("com.velocitypowered.proxy.connection.MinecraftConnection").getMethod("getAssociation");
} catch (NoSuchMethodException | ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
@@ -48,8 +50,8 @@ public class VelocityVersionProvider extends BaseVersionProvider {
private int getBackProtocol(UserConnection user) throws Exception {
//TODO use newly added Velocity netty event
ChannelHandler mcHandler = user.getChannel().pipeline().get("handler");
return Via.proxyPlatform().protocolDetectorService().serverProtocolVersion(
((ServerConnection) getAssociation.invoke(mcHandler)).getServerInfo().getName());
ServerConnection serverConnection = (ServerConnection) GET_ASSOCIATION.invoke(mcHandler);
return Via.proxyPlatform().protocolDetectorService().serverProtocolVersion(serverConnection.getServerInfo().getName());
}
private int getFrontProtocol(UserConnection user) throws Exception {
@@ -59,30 +61,32 @@ public class VelocityVersionProvider extends BaseVersionProvider {
.mapToInt(com.velocitypowered.api.network.ProtocolVersion::getProtocol);
// Modern forwarding mode needs 1.13 Login plugin message
if (VelocityViaInjector.getPlayerInfoForwardingMode != null
&& ((Enum<?>) VelocityViaInjector.getPlayerInfoForwardingMode.invoke(VelocityPlugin.PROXY.getConfiguration()))
if (VelocityViaInjector.GET_PLAYER_INFO_FORWARDING_MODE != null
&& ((Enum<?>) VelocityViaInjector.GET_PLAYER_INFO_FORWARDING_MODE.invoke(VelocityPlugin.PROXY.getConfiguration()))
.name().equals("MODERN")) {
versions = versions.filter(ver -> ver >= ProtocolVersion.v1_13.getVersion());
}
int[] compatibleProtocols = versions.toArray();
// Bungee supports it
if (Arrays.binarySearch(compatibleProtocols, playerVersion) >= 0)
if (Arrays.binarySearch(compatibleProtocols, playerVersion) >= 0) {
// Velocity supports it
return playerVersion;
}
// Older than bungee supports, get the lowest version
if (playerVersion < compatibleProtocols[0]) {
// Older than Velocity supports, get the lowest version
return compatibleProtocols[0];
}
// Loop through all protocols to get the closest protocol id that bungee supports (and that viaversion does too)
// Loop through all protocols to get the closest protocol id that Velocity supports (and that Via does too)
// TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work.
// This is more of a workaround for snapshot support by bungee.
// This is more of a workaround for snapshot support
for (int i = compatibleProtocols.length - 1; i >= 0; i--) {
int protocol = compatibleProtocols[i];
if (playerVersion > protocol && ProtocolVersion.isRegistered(protocol))
if (playerVersion > protocol && ProtocolVersion.isRegistered(protocol)) {
return protocol;
}
}
Via.getPlatform().getLogger().severe("Panic, no protocol id found for " + playerVersion);