Compare commits

...
68 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
Nassim Jahnke c9883c2638 4.6.1 Release 2023-03-16 20:44:53 +01:00
Nassim Jahnke 74fb55d96b Update yaml compat checker 2023-03-16 20:41:03 +01:00
Nassim Jahnke 4e844a0095 Small startup time improvements 2023-03-16 12:48:39 +01:00
Nassim Jahnke da7f8ea3b6 Be more safe 2023-03-15 16:21:15 +01:00
Nassim Jahnke 81c4e530e9 Possibly fix joinlistener on 1.19.4 Spigot 2023-03-15 16:15:21 +01:00
Nassim Jahnke b1524642aa Fix protocol detection on 1.19.4 Spigot
Fixes #3241
2023-03-15 10:09:45 +01:00
Nassim Jahnke a828c43f99 Remove ignoreCancelled from ArmorToggleListener, small cleanup
Spigot considers interacting with air "cancelled"
Fixes #3240
2023-03-15 09:20:21 +01:00
Nassim Jahnke fccfadf1b7 Handle falling blocks
Fixes #3244
2023-03-15 09:04:13 +01:00
lixfel 18b41c82c4 1.15.2 Spigot/Paper NoSuchMethodError YamlCompat fix (#3242) 2023-03-14 21:48:40 +01:00
Nassim Jahnke 27ee6f519e Bump version to 4.6.1-SNAPSHOT 2023-03-14 21:48:18 +01:00
93 changed files with 1555 additions and 350 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) {
@@ -131,4 +131,11 @@ public interface ViaManager {
* @param runnable runnable to be executed
*/
void addEnableListener(Runnable runnable);
/**
* Returns whether the manager has been initialized (and protocols have been loaded).
*
* @return whether the manager has been initialized
*/
boolean isInitialized();
}
@@ -256,6 +256,8 @@ public interface ViaVersionConfig {
*/
boolean is1_13TeamColourFix();
boolean shouldRegisterUserConnectionOnJoin();
/**
* Should we fix shift quick move action for 1.12 clients
*
@@ -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;
}
}
@@ -104,23 +104,22 @@ public interface ViaPlatform<T> {
PlatformTask runSync(Runnable runnable);
/**
* Run a task Sync after a interval
* This must be only used after plugin enable.
* Runs a synchronous task after a delay in ticks.
*
* @param runnable The task to run
* @param ticks The interval to run it after
* @return The Task ID
* @param runnable task to run
* @param delay delay in ticks to run it after
* @return created task
*/
PlatformTask runSync(Runnable runnable, long ticks);
PlatformTask runSync(Runnable runnable, long delay);
/**
* Run a task at a repeating interval.
* Runs a synchronous task at a repeating interval.
*
* @param runnable The task to run
* @param ticks The interval to run it at
* @return The Task ID
* @param runnable task to run
* @param period period in ticks to run at
* @return created task
*/
PlatformTask runRepeatingSync(Runnable runnable, long ticks);
PlatformTask runRepeatingSync(Runnable runnable, long period);
/**
* Get the online players
@@ -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);
}
@@ -57,10 +57,12 @@ public class ViaBukkitListener extends ViaListener implements Listener {
*/
@Override
public void register() {
if (isRegistered()) return;
if (isRegistered()) {
return;
}
plugin.getServer().getPluginManager().registerEvents(this, plugin);
setRegistered(true);
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public Plugin getPlugin() {
@@ -27,6 +27,7 @@ import com.viaversion.viaversion.api.platform.UnsupportedSoftware;
import com.viaversion.viaversion.api.platform.ViaPlatform;
import com.viaversion.viaversion.bukkit.commands.BukkitCommandHandler;
import com.viaversion.viaversion.bukkit.commands.BukkitCommandSender;
import com.viaversion.viaversion.bukkit.listeners.JoinListener;
import com.viaversion.viaversion.bukkit.platform.BukkitViaAPI;
import com.viaversion.viaversion.bukkit.platform.BukkitViaConfig;
import com.viaversion.viaversion.bukkit.platform.BukkitViaInjector;
@@ -54,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;
@@ -103,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);
}
@@ -171,13 +172,13 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player>
}
@Override
public PlatformTask runSync(Runnable runnable, long ticks) {
return new BukkitViaTask(getServer().getScheduler().runTaskLater(this, runnable, ticks));
public PlatformTask runSync(Runnable runnable, long delay) {
return new BukkitViaTask(getServer().getScheduler().runTaskLater(this, runnable, delay));
}
@Override
public PlatformTask runRepeatingSync(Runnable runnable, long ticks) {
return new BukkitViaTask(getServer().getScheduler().runTaskTimer(this, runnable, 0, ticks));
public PlatformTask runRepeatingSync(Runnable runnable, long period) {
return new BukkitViaTask(getServer().getScheduler().runTaskTimer(this, runnable, 0, period));
}
@Override
@@ -25,6 +25,7 @@ import com.viaversion.viaversion.bukkit.util.NMSUtil;
import io.netty.channel.Channel;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.logging.Level;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -41,13 +42,13 @@ public class JoinListener implements Listener {
private static final Field CHANNEL;
static {
Method gh = null;
Field conn = null, nm = null, ch = null;
Method getHandleMethod = null;
Field gamePacketListenerField = null, connectionField = null, channelField = null;
try {
gh = NMSUtil.obc("entity.CraftPlayer").getDeclaredMethod("getHandle");
conn = findField(gh.getReturnType(), "PlayerConnection", "ServerGamePacketListenerImpl");
nm = findField(conn.getType(), "NetworkManager", "Connection");
ch = findField(nm.getType(), "Channel");
getHandleMethod = NMSUtil.obc("entity.CraftPlayer").getDeclaredMethod("getHandle");
gamePacketListenerField = findField(getHandleMethod.getReturnType(), "PlayerConnection", "ServerGamePacketListenerImpl");
connectionField = findField(gamePacketListenerField.getType(), "NetworkManager", "Connection");
channelField = findField(connectionField.getType(), Class.forName("io.netty.channel.Channel"));
} catch (NoSuchMethodException | NoSuchFieldException | ClassNotFoundException e) {
Via.getPlatform().getLogger().log(
Level.WARNING,
@@ -55,22 +56,44 @@ public class JoinListener implements Listener {
"Login race condition fixer will be disabled.\n" +
" Some plugins that use ViaAPI on join event may work incorrectly.", e);
}
GET_HANDLE = gh;
CONNECTION = conn;
NETWORK_MANAGER = nm;
CHANNEL = ch;
GET_HANDLE = getHandleMethod;
CONNECTION = gamePacketListenerField;
NETWORK_MANAGER = connectionField;
CHANNEL = channelField;
}
// Loosely search a field with any name, as long as it matches a type name.
private static Field findField(Class<?> cl, String... types) throws NoSuchFieldException {
for (Field field : cl.getDeclaredFields()) {
for (String type : types)
if (field.getType().getSimpleName().equals(type))
return field;
private static Field findField(Class<?> clazz, String... types) throws NoSuchFieldException {
for (Field field : clazz.getDeclaredFields()) {
String fieldTypeName = field.getType().getSimpleName();
for (String type : types) {
if (!fieldTypeName.equals(type)) {
continue;
}
if (!Modifier.isPublic(field.getModifiers())) {
field.setAccessible(true);
}
return field;
}
}
throw new NoSuchFieldException(types[0]);
}
private static Field findField(Class<?> clazz, Class<?> fieldType) throws NoSuchFieldException {
for (Field field : clazz.getDeclaredFields()) {
if (field.getType() != fieldType) {
continue;
}
if (!Modifier.isPublic(field.getModifiers())) {
field.setAccessible(true);
}
return field;
}
throw new NoSuchFieldException(fieldType.getSimpleName());
}
@EventHandler(priority = EventPriority.LOWEST)
public void onJoin(PlayerJoinEvent e) {
if (CHANNEL == null) return;
@@ -27,42 +27,30 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
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, ignoreCancelled = true)
@EventHandler(priority = EventPriority.MONITOR)
public void itemUse(final PlayerInteractEvent event) {
if (!ENABLED) {
return;
}
final Player player = event.getPlayer();
if (!isOnPipe(player) || event.getItem() == null) {
final ItemStack item = event.getItem();
if (item == null || event.getHand() == null || !isOnPipe(player)) {
return;
}
final EquipmentSlot equipmentSlot = event.getItem().getType().getEquipmentSlot();
if (equipmentSlot != EquipmentSlot.HAND && equipmentSlot != EquipmentSlot.OFF_HAND) {
final ItemStack armor = player.getInventory().getItem(equipmentSlot);
final EquipmentSlot armorItemSlot = item.getType().getEquipmentSlot();
if (armorItemSlot != EquipmentSlot.HAND && armorItemSlot != EquipmentSlot.OFF_HAND) {
final PlayerInventory inventory = player.getInventory();
final ItemStack armor = inventory.getItem(armorItemSlot);
// If two pieces of armor are equal, the client will do nothing.
if (armor != null && armor.getType() != Material.AIR && !armor.equals(event.getItem())) {
player.updateInventory();
if (armor != null && armor.getType() != Material.AIR && !armor.equals(item)) {
inventory.setItem(event.getHand(), inventory.getItem(event.getHand()));
inventory.setItem(armorItemSlot, armor);
}
}
}
@@ -32,6 +32,7 @@ public class BukkitViaConfig extends AbstractViaConfig {
private boolean hitboxFix1_14;
private String blockConnectionMethod;
private boolean armorToggleFix;
private boolean registerUserConnectionOnJoin;
public BukkitViaConfig() {
super(new File(((Plugin) Via.getPlatform()).getDataFolder(), "config.yml"));
@@ -41,6 +42,7 @@ public class BukkitViaConfig extends AbstractViaConfig {
@Override
protected void loadFields() {
super.loadFields();
registerUserConnectionOnJoin = getBoolean("register-userconnections-on-join", true);
quickMoveActionFix = getBoolean("quick-move-action-fix", false);
hitboxFix1_9 = getBoolean("change-1_9-hitbox", false);
hitboxFix1_14 = getBoolean("change-1_14-hitbox", false);
@@ -52,6 +54,11 @@ public class BukkitViaConfig extends AbstractViaConfig {
protected void handleConfig(Map<String, Object> config) {
}
@Override
public boolean shouldRegisterUserConnectionOnJoin() {
return registerUserConnectionOnJoin;
}
@Override
public boolean is1_12QuickMoveActionFix() {
return quickMoveActionFix;
@@ -17,6 +17,7 @@
*/
package com.viaversion.viaversion.bukkit.platform;
import com.google.common.base.Preconditions;
import com.viaversion.viaversion.bukkit.handlers.BukkitChannelInitializer;
import com.viaversion.viaversion.bukkit.util.NMSUtil;
import com.viaversion.viaversion.platform.LegacyViaInjector;
@@ -35,6 +36,10 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class BukkitViaInjector extends LegacyViaInjector {
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 {
if (PaperViaInjector.PAPER_INJECTION_METHOD) {
@@ -62,10 +67,37 @@ public class BukkitViaInjector extends LegacyViaInjector {
return Bukkit.getUnsafe().getProtocolVersion();
}
// Time to go on a journey! The protocol version is hidden inside an int in ServerPing.ServerData
return HAS_WORLD_VERSION_PROTOCOL_VERSION ? cursedProtocolDetection() : veryCursedProtocolDetection();
}
private int cursedProtocolDetection() throws ReflectiveOperationException {
// Get the version from SharedConstants.getWorldVersion().getProtocolVersion()
Class<?> sharedConstantsClass = Class.forName("net.minecraft.SharedConstants");
Class<?> worldVersionClass = Class.forName("net.minecraft.WorldVersion");
Method getWorldVersionMethod = null;
for (Method method : sharedConstantsClass.getDeclaredMethods()) {
if (method.getReturnType() == worldVersionClass && method.getParameterTypes().length == 0) {
getWorldVersionMethod = method;
break;
}
}
Preconditions.checkNotNull(getWorldVersionMethod, "Failed to get world version method");
Object worldVersion = getWorldVersionMethod.invoke(null);
for (Method method : worldVersionClass.getDeclaredMethods()) {
if (method.getReturnType() == int.class && method.getParameterTypes().length == 0) {
return (int) method.invoke(worldVersion);
}
}
throw new IllegalAccessException("Failed to find protocol version method in WorldVersion");
}
private int veryCursedProtocolDetection() throws ReflectiveOperationException {
// Time to go on a journey! The protocol version is hidden inside an int in ServerPing.ServerData, that is only set once the server has ticked once
// Grab a static instance of the server
Class<?> serverClazz = NMSUtil.nms("MinecraftServer", "net.minecraft.server.MinecraftServer");
Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer");
Preconditions.checkNotNull(server, "Failed to get server instance");
// Grab the ping class and find the field to access it
Class<?> pingClazz = NMSUtil.nms(
@@ -80,6 +112,7 @@ public class BukkitViaInjector extends LegacyViaInjector {
break;
}
}
Preconditions.checkNotNull(ping, "Failed to get server ping");
// Now get the ServerData inside ServerPing
Class<?> serverDataClass = NMSUtil.nms(
@@ -94,6 +127,7 @@ public class BukkitViaInjector extends LegacyViaInjector {
break;
}
}
Preconditions.checkNotNull(serverData, "Failed to get server data");
// Get protocol version field
for (Field field : serverDataClass.getDeclaredFields()) {
@@ -155,7 +189,7 @@ public class BukkitViaInjector extends LegacyViaInjector {
@Override
public boolean lateProtocolVersionSetting() {
return !PaperViaInjector.PAPER_PROTOCOL_METHOD;
return !(PaperViaInjector.PAPER_PROTOCOL_METHOD || HAS_WORLD_VERSION_PROTOCOL_VERSION);
}
public boolean isBinded() {
@@ -50,17 +50,16 @@ 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.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.scheduler.BukkitTask;
public class BukkitViaLoader implements ViaPlatformLoader {
private final ViaVersionPlugin plugin;
private final Set<Listener> listeners = new HashSet<>();
private final Set<BukkitTask> tasks = new HashSet<>();
private final ViaVersionPlugin plugin;
private HandItemCache handItemCache;
public BukkitViaLoader(ViaVersionPlugin plugin) {
@@ -68,21 +67,21 @@ public class BukkitViaLoader implements ViaPlatformLoader {
}
public void registerListener(Listener listener) {
Bukkit.getPluginManager().registerEvents(storeListener(listener), plugin);
plugin.getServer().getPluginManager().registerEvents(listener, plugin);
}
@Deprecated/*(forRemoval = true)*/
public <T extends Listener> T storeListener(T listener) {
listeners.add(listener);
return listener;
}
@Override
public void load() {
// Update Listener
registerListener(new UpdateListener());
// Login listener
registerListener(new JoinListener());
if (Via.getConfig().shouldRegisterUserConnectionOnJoin()) {
registerListener(new JoinListener());
}
/* Base Protocol */
final ViaVersionPlugin plugin = (ViaVersionPlugin) Bukkit.getPluginManager().getPlugin("ViaVersion");
@@ -92,13 +91,18 @@ public class BukkitViaLoader implements ViaPlatformLoader {
ProtocolSupportCompat.registerPSConnectListener(plugin);
}
if (!Via.getAPI().getServerVersion().isKnown()) {
Via.getPlatform().getLogger().severe("Server version has not been loaded yet, cannot register additional listeners");
return;
}
int serverProtocolVersion = Via.getAPI().getServerVersion().lowestSupportedVersion();
/* 1.9 client to 1.8 server */
if (serverProtocolVersion < ProtocolVersion.v1_9.getVersion()) {
storeListener(new ArmorListener(plugin)).register();
storeListener(new DeathListener(plugin)).register();
storeListener(new BlockListener(plugin)).register();
new ArmorListener(plugin).register();
new DeathListener(plugin).register();
new BlockListener(plugin).register();
if (plugin.getConf().isItemCache()) {
handItemCache = new HandItemCache();
@@ -110,7 +114,7 @@ public class BukkitViaLoader implements ViaPlatformLoader {
boolean use1_9Fix = plugin.getConf().is1_9HitboxFix() && serverProtocolVersion < ProtocolVersion.v1_9.getVersion();
if (use1_9Fix || plugin.getConf().is1_14HitboxFix()) {
try {
storeListener(new PlayerSneakListener(plugin, use1_9Fix, plugin.getConf().is1_14HitboxFix())).register();
new PlayerSneakListener(plugin, use1_9Fix, plugin.getConf().is1_14HitboxFix()).register();
} catch (ReflectiveOperationException e) {
Via.getPlatform().getLogger().warning("Could not load hitbox fix - please report this on our GitHub");
e.printStackTrace();
@@ -121,7 +125,7 @@ public class BukkitViaLoader implements ViaPlatformLoader {
if (serverProtocolVersion < ProtocolVersion.v1_15.getVersion()) {
try {
Class.forName("org.bukkit.event.entity.EntityToggleGlideEvent");
storeListener(new EntityToggleGlideListener(plugin)).register();
new EntityToggleGlideListener(plugin).register();
} catch (ClassNotFoundException ignored) {
}
}
@@ -138,12 +142,12 @@ public class BukkitViaLoader implements ViaPlatformLoader {
}
}
if (paper) {
storeListener(new PaperPatch(plugin)).register();
new PaperPatch(plugin).register();
}
}
if (serverProtocolVersion < ProtocolVersion.v1_19_4.getVersion() && plugin.getConf().isArmorToggleFix()) {
storeListener(new ArmorToggleListener(plugin)).register();
if (serverProtocolVersion < ProtocolVersion.v1_19_4.getVersion() && plugin.getConf().isArmorToggleFix() && hasGetHandMethod()) {
new ArmorToggleListener(plugin).register();
}
/* Providers */
@@ -189,16 +193,22 @@ public class BukkitViaLoader implements ViaPlatformLoader {
}
if (serverProtocolVersion < ProtocolVersion.v1_19.getVersion()) {
Via.getManager().getProviders().use(AckSequenceProvider.class, new BukkitAckSequenceProvider(plugin));
storeListener(new BlockBreakListener(plugin)).register();
new BlockBreakListener(plugin).register();
}
}
private boolean hasGetHandMethod() {
try {
PlayerInteractEvent.class.getDeclaredMethod("getHand");
Material.class.getMethod("getEquipmentSlot");
return true;
} catch (NoSuchMethodException e) {
return false;
}
}
@Override
public void unload() {
for (Listener listener : listeners) {
HandlerList.unregisterAll(listener);
}
listeners.clear();
for (BukkitTask task : tasks) {
task.cancel();
}
@@ -126,13 +126,13 @@ public class BungeePlugin extends Plugin implements ViaServerProxyPlatform<Proxi
}
@Override
public PlatformTask runSync(Runnable runnable, long ticks) {
return new BungeeViaTask(getProxy().getScheduler().schedule(this, runnable, ticks * 50, TimeUnit.MILLISECONDS));
public PlatformTask runSync(Runnable runnable, long delay) {
return new BungeeViaTask(getProxy().getScheduler().schedule(this, runnable, delay * 50, TimeUnit.MILLISECONDS));
}
@Override
public PlatformTask runRepeatingSync(Runnable runnable, long ticks) {
return runRepeatingAsync(runnable, ticks);
public PlatformTask runRepeatingSync(Runnable runnable, long period) {
return runRepeatingAsync(runnable, period);
}
@Override
@@ -63,6 +63,7 @@ public class ViaManagerImpl implements ViaManager {
private final Set<String> subPlatforms = new HashSet<>();
private List<Runnable> enableListeners = new ArrayList<>();
private PlatformTask<?> mappingLoadingTask;
private boolean initialized;
public ViaManagerImpl(ViaPlatform<?> platform, ViaInjector injector, ViaCommandHandler commandHandler, ViaPlatformLoader loader) {
this.platform = platform;
@@ -105,6 +106,8 @@ public class ViaManagerImpl implements ViaManager {
listener.run();
}
enableListeners = null;
initialized = true;
}
public void onServerLoaded() {
@@ -149,9 +152,6 @@ public class ViaManagerImpl implements ViaManager {
// Check for unsupported plugins/software
unsupportedSoftwareWarning();
// Load Listeners / Tasks
protocolManager.onServerLoaded();
// Load Platform
loader.load();
// Common 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("");
}
@@ -324,6 +325,11 @@ public class ViaManagerImpl implements ViaManager {
enableListeners.add(runnable);
}
@Override
public boolean isInitialized() {
return initialized;
}
public static final class ViaManagerBuilder {
private ViaPlatform<?> platform;
private ViaInjector injector;
@@ -383,6 +383,11 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
return nbtArrayFix;
}
@Override
public boolean shouldRegisterUserConnectionOnJoin() {
return false;
}
@Override
public boolean is1_12QuickMoveActionFix() {
return false;
@@ -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;
@@ -109,11 +110,10 @@ public class ProtocolManagerImpl implements ProtocolManager {
// Input Version -> Output Version & Protocol (Allows fast lookup)
private final Int2ObjectMap<Int2ObjectMap<Protocol>> registryMap = new Int2ObjectOpenHashMap<>(32);
private final Map<Class<? extends Protocol>, Protocol<?, ?, ?, ?>> protocols = new HashMap<>();
private final Map<Class<? extends Protocol>, Protocol<?, ?, ?, ?>> protocols = new HashMap<>(64);
private final Map<ProtocolPathKey, List<ProtocolPathEntry>> pathCache = new ConcurrentHashMap<>();
private final Set<Integer> supportedVersions = new HashSet<>();
private final List<Pair<Range<Integer>, Protocol>> baseProtocols = Lists.newCopyOnWriteArrayList();
private final List<Protocol> registerList = new ArrayList<>();
private final ReadWriteLock mappingLoaderLock = new ReentrantReadWriteLock();
private Map<Class<? extends Protocol>, CompletableFuture<Void>> mappingLoaderFutures = new HashMap<>();
@@ -181,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
@@ -208,11 +210,9 @@ public class ProtocolManagerImpl implements ProtocolManager {
protocolMap.put(serverVersion, protocol);
}
if (Via.getPlatform().isPluginEnabled()) {
protocol.register(Via.getManager().getProviders());
protocol.register(Via.getManager().getProviders());
if (Via.getManager().isInitialized()) {
refreshVersions();
} else {
registerList.add(protocol);
}
if (protocol.hasMappingDataToLoad()) {
@@ -232,11 +232,9 @@ public class ProtocolManagerImpl implements ProtocolManager {
baseProtocol.initialize();
baseProtocols.add(new Pair<>(supportedProtocols, baseProtocol));
if (Via.getPlatform().isPluginEnabled()) {
baseProtocol.register(Via.getManager().getProviders());
baseProtocol.register(Via.getManager().getProviders());
if (Via.getManager().isInitialized()) {
refreshVersions();
} else {
registerList.add(baseProtocol);
}
}
@@ -498,16 +496,6 @@ public class ProtocolManagerImpl implements ProtocolManager {
return new PacketWrapperImpl(packetId, buf, connection);
}
/**
* Called when the server is enabled, to register any non-registered listeners.
*/
public void onServerLoaded() {
for (Protocol protocol : registerList) {
protocol.register(Via.getManager().getProviders());
}
registerList.clear();
}
public void shutdownLoaderExecutor() {
Preconditions.checkArgument(!mappingsLoaded);
@@ -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;
@@ -29,6 +30,16 @@ 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 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) {
// Not used for chat messages, so no need for url extraction
Component component = LegacyComponentSerializer.legacySection().deserialize(message);
@@ -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,15 +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;
@@ -42,7 +43,6 @@ import java.util.Base64;
public final class Protocol1_19_4To1_19_3 extends AbstractProtocol<ClientboundPackets1_19_3, ClientboundPackets1_19_4, ServerboundPackets1_19_3, ServerboundPackets1_19_4> {
public static final MappingData MAPPINGS = new MappingData();
private static final JsonElement EMPTY_COMPONENT = GsonComponentSerializer.gson().serializeToTree(Component.empty());
private final EntityPackets entityRewriter = new EntityPackets(this);
private final InventoryPackets itemRewriter = new InventoryPackets(this);
@@ -55,12 +55,12 @@ 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);
soundRewriter.register1_19_3Sound(ClientboundPackets1_19_3.SOUND);
new CommandRewriter<ClientboundPackets1_19_3>(this) {
@Override
public void handleArgument(final PacketWrapper wrapper, final String argumentType) throws Exception {
@@ -78,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, 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);
});
}
@@ -98,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);
}
@@ -106,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
@@ -122,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())));
}
});
@@ -131,7 +202,7 @@ public final class EntityPackets extends EntityRewriter<ClientboundPackets1_19_3
wrapper.write(Type.BYTE, event);
});
registerTrackerWithData1_19(ClientboundPackets1_19_3.SPAWN_ENTITY, null);
registerTrackerWithData1_19(ClientboundPackets1_19_3.SPAWN_ENTITY, Entity1_19_4Types.FALLING_BLOCK);
registerRemoveEntities(ClientboundPackets1_19_3.REMOVE_ENTITIES);
registerMetadataRewriter(ClientboundPackets1_19_3.ENTITY_METADATA, Types1_19_3.METADATA_LIST, Types1_19_4.METADATA_LIST);
}
@@ -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);
}
}
}
@@ -53,13 +53,10 @@ public class InventoryPackets {
// Send 2 properties, splitting it into enchantID & level
final short level = (short) (value >> 8);
final short enchantID = (short) (value & 0xFF);
wrapper.create(wrapper.getId(), new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.write(Type.UNSIGNED_BYTE, windowId);
wrapper.write(Type.SHORT, property);
wrapper.write(Type.SHORT, enchantID);
}
wrapper.create(wrapper.getId(), propertyPacket -> {
propertyPacket.write(Type.UNSIGNED_BYTE, windowId);
propertyPacket.write(Type.SHORT, property);
propertyPacket.write(Type.SHORT, enchantID);
}).scheduleSend(Protocol1_9To1_8.class);
wrapper.set(Type.SHORT, 0, (short) (property + 3));
@@ -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 {
@@ -39,8 +39,9 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
@SuppressWarnings("VulnerableCodeUsages")
public abstract class Config implements ConfigurationProvider {
private static final YamlCompat YAMP_COMPAT = YamlCompat.isVersion2() ? new Yaml2Compat() : new Yaml1Compat();
private static final YamlCompat YAMP_COMPAT = YamlCompat.isVersion1() ? new Yaml1Compat() : new Yaml2Compat();
private static final ThreadLocal<Yaml> YAML = ThreadLocal.withInitial(() -> {
DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
@@ -102,6 +102,9 @@ tracking-max-kick-msg: "You are sending too many packets, :("
# MULTIPLE VERSIONS OPTIONS #
#----------------------------------------------------------#
#
# Whether to make sure ViaVersion's UserConnection object is already available in the PlayerJoinEvent.
# You may disable this for faster startup/join time if you are 100% sure no plugin requires this.
register-userconnections-on-join: true
# Should we enable our hologram patch?
# If they're in the wrong place enable this
hologram-patch: false
@@ -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
}
@@ -71,12 +71,12 @@ public final class TestPlatform implements ViaPlatform {
}
@Override
public PlatformTask runSync(Runnable runnable, long ticks) {
public PlatformTask runSync(Runnable runnable, long delay) {
return null;
}
@Override
public PlatformTask runRepeatingSync(Runnable runnable, long ticks) {
public PlatformTask runRepeatingSync(Runnable runnable, long period) {
return null;
}
@@ -27,9 +27,9 @@ public interface YamlCompat {
SafeConstructor createSafeConstructor();
static boolean isVersion2() {
static boolean isVersion1() {
try {
Representer.class.getDeclaredConstructor(DumperOptions.class);
SafeConstructor.class.getDeclaredConstructor();
return true;
} catch (NoSuchMethodException e) {
return false;
+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.0
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
@@ -153,14 +153,14 @@ public class SpongePlugin implements ViaPlatform<Player> {
}
@Override
public PlatformTask runSync(Runnable runnable, long ticks) {
final Task task = Task.builder().plugin(container).execute(runnable).delay(Ticks.of(ticks)).build();
public PlatformTask runSync(Runnable runnable, long delay) {
final Task task = Task.builder().plugin(container).execute(runnable).delay(Ticks.of(delay)).build();
return new SpongeViaTask(game.server().scheduler().submit(task));
}
@Override
public PlatformTask runRepeatingSync(Runnable runnable, long ticks) {
final Task task = Task.builder().plugin(container).execute(runnable).interval(Ticks.of(ticks)).build();
public PlatformTask runRepeatingSync(Runnable runnable, long period) {
final Task task = Task.builder().plugin(container).execute(runnable).interval(Ticks.of(period)).build();
return new SpongeViaTask(game.server().scheduler().submit(task));
}
@@ -155,17 +155,17 @@ public class VelocityPlugin implements ViaServerProxyPlatform<Player> {
}
@Override
public PlatformTask runSync(Runnable runnable, long ticks) {
public PlatformTask runSync(Runnable runnable, long delay) {
return new VelocityViaTask(
PROXY.getScheduler()
.buildTask(this, runnable)
.delay(ticks * 50, TimeUnit.MILLISECONDS).schedule()
.delay(delay * 50, TimeUnit.MILLISECONDS).schedule()
);
}
@Override
public PlatformTask runRepeatingSync(Runnable runnable, long ticks) {
return runRepeatingAsync(runnable, ticks);
public PlatformTask runRepeatingSync(Runnable runnable, long period) {
return runRepeatingAsync(runnable, period);
}
@Override
@@ -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);