Compare commits

...
61 Commits
Author SHA1 Message Date
KennyTV b3e8ad9164 3.2.0 Release, 1.16.4 2020-11-02 19:40:04 +01:00
KennyTV c3501a831e Merge remote-tracking branch 'origin/master' into dev 2020-11-02 18:37:01 +01:00
Myles 9821cb1b16 Merge pull request #1723 from creeper123123321/backendinjection
Velocity Backend injection / Velocity 1.1.0
2020-11-02 17:29:31 +00:00
Myles bba1f2acf0 Merge pull request #2162 from lennardk/fix-1.11-sound-rewrite
Fix sound ID shift in 1.11
2020-11-02 16:19:27 +00:00
Lennard Klein 1afbff18ef Fix sound ID shift in 1.11
This possibly got broken in the rewrite in dc62394.
Fixes ender pearl throw and experience bottle throw/pickup sounds.
2020-11-01 14:51:34 +01:00
MrMicky 56ec689841 Update protocol versions (#2156) 2020-10-29 12:53:16 +01:00
Myles 3189501b78 Revert "Remove minecraft libraries"
This reverts commit 1c23103517.
2020-10-29 11:10:36 +00:00
Myles 1c23103517 Remove minecraft libraries
Not needed AFAIK
2020-10-29 11:01:07 +00:00
Five (Xer) 06e1b90f29 Finalize Velocity-1.1.0 2020-10-28 20:10:15 +01:00
creeper123123321 acd79fc661 readd snakeyaml as provided dependency 2020-10-28 19:51:02 +01:00
creeper123123321 18bde6ee37 don't shade snakeyaml, closes #1959 2020-10-28 19:51:02 +01:00
creeper123123321 72f8052e58 code cleanup 2020-10-28 19:51:02 +01:00
creeper123123321 0343be6915 remove unused code 2020-10-28 19:51:02 +01:00
creeper123123321 000a034836 draft -> buf 2020-10-28 19:51:02 +01:00
creeper123123321 2d33447fc1 fixed backend compression, remove debug 2020-10-28 19:51:02 +01:00
creeper123123321 bcb76350a1 fix decoder 2020-10-28 19:51:02 +01:00
creeper123123321 485f4fa070 remove velocityconnectionmanager 2020-10-28 19:51:02 +01:00
creeper123123321 b1e60f5f1b fix compiling 2020-10-28 19:51:02 +01:00
creeper123123321 6c3479e739 rebased on master 2020-10-28 19:51:02 +01:00
creeper123123321 4813cc3077 inject into velocity backend (currently broken)
Add client-side mode for UserConnection

remove unused code

fix duplicate method on rebase
2020-10-28 19:51:01 +01:00
KennyTV 69c8cf8ffb Smaller workaround for lore italics in 1.13->1.14 2020-10-28 15:19:00 +01:00
KennyTV 510ff4e6a1 Improve 1.13->1.14 lore conversion, remove noisy workaround for a non-issue in legacy to json conversion
If people want to have white, unformatted text in their lore, they should do exactly that; add a white color, not reset to default
Fixes #2158
2020-10-28 14:36:22 +01:00
DaPorkchop_ a6043c14cd Fix 1.16.2 multi block change packet order (#2138) 2020-10-28 08:43:22 +01:00
KennyTV 1a4c34afcf 1.16.4-rc1 2020-10-27 18:34:59 +01:00
KennyTV 2f9ec6f2aa Remove redundant/already implicit check in VersionRange 2020-10-24 22:39:17 +02:00
KennyTV bc2f6a423f Fix typo 2020-10-24 11:14:11 +02:00
KennyTV 0986b0982c Fix dontbugme command
Fixes #2152
2020-10-24 11:13:16 +02:00
KennyTV 9a24129e49 1.16.4-pre2 2020-10-22 17:43:38 +02:00
KennyTV c8029bdbdf Use getters instead of inlining 2020-10-21 14:17:51 +02:00
KennyTV 1129c17489 Improve ProtocolVersion subversion/range handling
Closes #2041
2020-10-21 14:02:31 +02:00
KennyTV f313b5b617 Merge branch 'master' into dev 2020-10-18 22:41:23 +02:00
RK_01 765f92bfe5 Correct 1.9.x -> 1.10 sound pitch adjustments (#2139) 2020-10-18 22:37:30 +02:00
KennyTV edd71bf8ab Fix version blocking on 1.8
Fixes #2142
2020-10-16 18:26:15 +02:00
KennyTV 7d96efc645 Minor ProtocolVersion refactor 2020-10-16 18:21:45 +02:00
KennyTV 6cb2837d77 Merge remote-tracking branch 'origin/master' into dev 2020-10-16 16:56:29 +02:00
KennyTV 08a8268852 Handle book edit change 2020-10-15 17:57:12 +02:00
DaPorkchop_ 54b6d1c21c Fix entity attributes length prefix (#2136) 2020-10-14 15:40:39 +02:00
RK_01 71341a9381 Fix 1.11.1 -> 1.12 show_achievement translation (#2120) 2020-10-12 13:32:06 +02:00
KennyTV 5eccc2e3cd Merge branch 'master' into dev 2020-10-12 10:18:50 +02:00
KennyTV 0015682fe4 Add warning on startup for 1.8 users 2020-10-12 09:51:33 +02:00
KennyTV 107892fb24 Hopefully finish preparation, minor optimizations 2020-10-07 12:50:23 +02:00
KennyTV 6371b77b94 Prepare hackery for 1.16.4 2020-10-07 12:32:52 +02:00
KennyTV 03ba058a9b Rewrite areaeffectcloud in 1.13->1.13.1 2020-09-25 14:49:01 +02:00
connorhartley 750c5ed9a7 Fix falling_dust ID in ParticleMappings 2020-09-25 10:00:09 +02:00
Seanoo1 14afb884ad Update README.md 2020-09-21 19:49:59 +02:00
Kim Hallberg ab788554bf Update LICENSE to 2020 2020-09-21 19:49:42 +02:00
KennyTV b8c204b306 Rewrite area effect cloud data
Fixes #2082
2020-09-21 11:12:32 +02:00
KennyTV 52f542774f Automated particle rewriting 2020-09-21 09:53:04 +02:00
KennyTV e502f2c96d Clarify error in BlockChangeRecord1_16_2 2020-09-13 15:26:37 +02:00
terrarier2111 8d904ca010 Update BungeeCord version to 1.16-R0.4-SNAPSHOT (#2083) 2020-09-12 20:04:52 +02:00
terrarier2111 9a6b0664e3 Update BungeePlugin.java (#2080) 2020-09-12 17:43:09 +02:00
KennyTV 5f1472a18d Merge branch 'dev' into master
# Conflicts:
#	bukkit-legacy/pom.xml
#	bukkit/pom.xml
#	bungee/pom.xml
#	common/pom.xml
#	fabric/pom.xml
#	jar/pom.xml
#	pom.xml
#	sponge-legacy/pom.xml
#	sponge/pom.xml
#	velocity/pom.xml
2020-09-10 16:37:35 +02:00
KennyTV 9dff193c09 Minor cleanup in 1.13->1.13.1 protocol 2020-09-09 15:51:30 +02:00
KennyTV df9508ff3c Make mapping loading considerably faster 2020-09-09 10:54:56 +02:00
KennyTV 414f561673 Use FU collections in ChunkSection, pre-size palette 2020-09-08 11:10:16 +02:00
KennyTV 074edf1b48 Fix falling block id rewrite 2020-09-08 11:01:00 +02:00
KennyTV a0a229fa29 Make pipeline fail-safe limit changeable
☠
2020-09-08 09:06:54 +02:00
KennyTV 1ea548f05d Avoid List creation and collection reversal in transforming 2020-09-06 12:42:37 +02:00
KennyTV b7bf993795 Warn with unmapped id when missing 2020-09-04 11:04:44 +02:00
KennyTV a709382d25 Fix NPE 2020-09-04 11:04:44 +02:00
KennyTV d36def89e1 Abstract mapping loading 2020-09-04 11:04:44 +02:00
128 changed files with 2735 additions and 1438 deletions

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2019
Copyright (c) 2020
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+1 -1
View File
@@ -9,7 +9,7 @@ Supported Versions:
![Table (https://i.imgur.com/0u20Y2u.png)](https://i.imgur.com/0u20Y2u.png)
On Bukkit you may also use ProtocolSupport, but ensure you have the right build for your server version.
On Paper you may also use ProtocolSupport, but ensure you have the right build for your server version.
**User Docs:** https://docs.viaversion.com/display/VIAVERSION/
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId>
<version>3.1.1</version>
<version>3.2.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId>
<version>3.1.1</version>
<version>3.2.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -61,7 +61,7 @@ public class BukkitEncodeHandler extends MessageToByteEncoder implements ViaHand
@Override
public void transform(ByteBuf bytebuf) throws Exception {
info.checkOutgoingPacket();
if (!info.checkOutgoingPacket()) throw CancelEncoderException.generate(null);
if (!info.shouldTransformPacket()) return;
info.transformOutgoing(bytebuf, CancelEncoderException::generate);
}
@@ -51,7 +51,7 @@ public class PlayerSneakListener extends ViaBukkitListener {
// From 1.9 upwards the server hitbox is set in every entity tick, so we have to reset it everytime
if (ProtocolRegistry.SERVER_PROTOCOL >= ProtocolVersion.v1_9.getId()) {
if (ProtocolRegistry.SERVER_PROTOCOL >= ProtocolVersion.v1_9.getVersion()) {
sneaking = new WeakHashMap<>();
useCache = true;
plugin.getServer().getScheduler().runTaskTimer(plugin, new Runnable() {
@@ -79,7 +79,7 @@ public class PlayerSneakListener extends ViaBukkitListener {
if (info == null) return;
int protocolVersion = info.getProtocolVersion();
if (is1_14Fix && protocolVersion >= ProtocolVersion.v1_14.getId()) {
if (is1_14Fix && protocolVersion >= ProtocolVersion.v1_14.getVersion()) {
setHeight(player, event.isSneaking() ? HEIGHT_1_14 : STANDING_HEIGHT);
if (event.isSneaking())
sneakingUuids.add(player.getUniqueId());
@@ -91,7 +91,7 @@ public class PlayerSneakListener extends ViaBukkitListener {
sneaking.put(player, true);
else
sneaking.remove(player);
} else if (is1_9Fix && protocolVersion >= ProtocolVersion.v1_9.getId()) {
} else if (is1_9Fix && protocolVersion >= ProtocolVersion.v1_9.getVersion()) {
setHeight(player, event.isSneaking() ? HEIGHT_1_9 : STANDING_HEIGHT);
if (!useCache) return;
if (event.isSneaking())
@@ -25,7 +25,6 @@ import us.myles.ViaVersion.bukkit.providers.BukkitBlockConnectionProvider;
import us.myles.ViaVersion.bukkit.providers.BukkitInventoryQuickMoveProvider;
import us.myles.ViaVersion.bukkit.providers.BukkitViaBulkChunkTranslator;
import us.myles.ViaVersion.bukkit.providers.BukkitViaMovementTransmitter;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.providers.InventoryQuickMoveProvider;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionData;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.providers.BlockConnectionProvider;
@@ -72,7 +71,7 @@ public class BukkitViaLoader implements ViaPlatformLoader {
ClassGenerator.registerPSConnectListener(plugin);
/* 1.9 client to 1.8 server */
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getId()) {
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getVersion()) {
storeListener(new ArmorListener(plugin)).register();
storeListener(new DeathListener(plugin)).register();
storeListener(new BlockListener(plugin)).register();
@@ -83,8 +82,8 @@ public class BukkitViaLoader implements ViaPlatformLoader {
}
}
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_14.getId()) {
boolean use1_9Fix = plugin.getConf().is1_9HitboxFix() && ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getId();
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_14.getVersion()) {
boolean use1_9Fix = plugin.getConf().is1_9HitboxFix() && ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getVersion();
if (use1_9Fix || plugin.getConf().is1_14HitboxFix()) {
try {
storeListener(new PlayerSneakListener(plugin, use1_9Fix, plugin.getConf().is1_14HitboxFix())).register();
@@ -95,7 +94,7 @@ public class BukkitViaLoader implements ViaPlatformLoader {
}
}
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_15.getId()) {
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_15.getVersion()) {
try {
Class.forName("org.bukkit.event.entity.EntityToggleGlideEvent");
storeListener(new EntityToggleGlideListener(plugin)).register();
@@ -106,13 +105,13 @@ public class BukkitViaLoader implements ViaPlatformLoader {
if ((Bukkit.getVersion().toLowerCase(Locale.ROOT).contains("paper")
|| Bukkit.getVersion().toLowerCase(Locale.ROOT).contains("taco")
|| Bukkit.getVersion().toLowerCase(Locale.ROOT).contains("torch"))
&& ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_12.getId()) {
&& ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_12.getVersion()) {
plugin.getLogger().info("Enabling Paper/TacoSpigot/Torch patch: Fixes block placement.");
storeListener(new PaperPatch(plugin)).register();
}
/* Providers */
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getId()) {
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getVersion()) {
Via.getManager().getProviders().use(BulkChunkTranslatorProvider.class, new BukkitViaBulkChunkTranslator());
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BukkitViaMovementTransmitter());
@@ -141,12 +140,12 @@ public class BukkitViaLoader implements ViaPlatformLoader {
});
}
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_12.getId()) {
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_12.getVersion()) {
if (plugin.getConf().is1_12QuickMoveActionFix()) {
Via.getManager().getProviders().use(InventoryQuickMoveProvider.class, new BukkitInventoryQuickMoveProvider());
}
}
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_13.getId()) {
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_13.getVersion()) {
if (Via.getConfig().getBlockConnectionMethod().equalsIgnoreCase("world")) {
BukkitBlockConnectionProvider blockConnectionProvider = new BukkitBlockConnectionProvider();
Via.getManager().getProviders().use(BlockConnectionProvider.class, blockConnectionProvider);
@@ -58,7 +58,7 @@ public class BukkitInventoryQuickMoveProvider extends InventoryQuickMoveProvider
if (slotId >= 36 && slotId <= 44) {
int protocolId = ProtocolRegistry.SERVER_PROTOCOL;
// this seems to be working just fine.
if (protocolId == ProtocolVersion.v1_8.getId()) {
if (protocolId == ProtocolVersion.v1_8.getVersion()) {
return false;
}
}
@@ -89,7 +89,7 @@ public class BukkitInventoryQuickMoveProvider extends InventoryQuickMoveProvider
InventoryType tinvtype = tinv == null ? null : tinv.getType(); // can this even be null?
if (tinvtype != null) {
int protocolId = ProtocolRegistry.SERVER_PROTOCOL;
if (protocolId == ProtocolVersion.v1_8.getId()) {
if (protocolId == ProtocolVersion.v1_8.getVersion()) {
if (tinvtype == InventoryType.BREWING) {
// 1.9 added the blaze powder slot to brewing stand fix for 1.8 servers
if (slotId >= 5 && slotId <= 40) {
@@ -118,9 +118,9 @@ public class BukkitInventoryQuickMoveProvider extends InventoryQuickMoveProvider
ReflectionUtil.set(packet, "d", storage.getActionId());
ReflectionUtil.set(packet, "item", nmsItem);
int protocolId = ProtocolRegistry.SERVER_PROTOCOL;
if (protocolId == ProtocolVersion.v1_8.getId()) {
if (protocolId == ProtocolVersion.v1_8.getVersion()) {
ReflectionUtil.set(packet, "shift", 1);
} else if (protocolId >= ProtocolVersion.v1_9.getId()) { // 1.9+
} else if (protocolId >= ProtocolVersion.v1_9.getVersion()) { // 1.9+
ReflectionUtil.set(packet, "shift", clickTypeEnum);
}
} catch (Exception e) {
@@ -157,7 +157,7 @@ public class BukkitInventoryQuickMoveProvider extends InventoryQuickMoveProvider
try {
this.windowClickPacketClass = NMSUtil.nms("PacketPlayInWindowClick");
int protocolId = ProtocolRegistry.SERVER_PROTOCOL;
if (protocolId >= ProtocolVersion.v1_9.getId()) {
if (protocolId >= ProtocolVersion.v1_9.getVersion()) {
Class<?> eclassz = NMSUtil.nms("InventoryClickType");
Object[] constants = eclassz.getEnumConstants();
this.clickTypeEnum = constants[1]; // QUICK_MOVE
@@ -186,7 +186,7 @@ public class BukkitInventoryQuickMoveProvider extends InventoryQuickMoveProvider
private boolean isSupported() {
int protocolId = ProtocolRegistry.SERVER_PROTOCOL;
if (protocolId >= ProtocolVersion.v1_8.getId() && protocolId <= ProtocolVersion.v1_11_1.getId()) {
if (protocolId >= ProtocolVersion.v1_8.getVersion() && protocolId <= ProtocolVersion.v1_11_1.getVersion()) {
return true; // 1.8-1.11.2
}
// this is not needed on 1.12+ servers
+1 -1
View File
@@ -5,7 +5,7 @@
<parent>
<artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId>
<version>3.1.1</version>
<version>3.2.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -40,7 +40,7 @@ public class BungeePlugin extends Plugin implements ViaPlatform<ProxiedPlayer>,
@Override
public void onLoad() {
try {
ProtocolConstants.class.getField("MINECRAFT_1_15_2");
ProtocolConstants.class.getField("MINECRAFT_1_16_3");
} catch (NoSuchFieldException e) {
getLogger().warning(" / \\");
getLogger().warning(" / \\");
@@ -85,6 +85,11 @@ public class BungeePlugin extends Plugin implements ViaPlatform<ProxiedPlayer>,
return getProxy().getVersion();
}
@Override
public boolean isProxy() {
return true;
}
@Override
public String getPluginVersion() {
return getDescription().getVersion();
@@ -136,8 +141,9 @@ public class BungeePlugin extends Plugin implements ViaPlatform<ProxiedPlayer>,
@Override
public boolean kickPlayer(UUID uuid, String message) {
if (getProxy().getPlayer(uuid) != null) {
getProxy().getPlayer(uuid).disconnect(message);
ProxiedPlayer player = getProxy().getPlayer(uuid);
if (player != null) {
player.disconnect(message);
return true;
}
return false;
@@ -22,7 +22,7 @@ public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
@Override
protected void encode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List<Object> out) throws Exception {
info.checkOutgoingPacket();
if (!info.checkOutgoingPacket()) throw CancelEncoderException.generate(null);
if (!info.shouldTransformPacket()) {
out.add(bytebuf.retain());
return;
@@ -7,7 +7,6 @@ import net.md_5.bungee.api.event.ServerSwitchEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.score.Team;
import net.md_5.bungee.event.EventHandler;
import net.md_5.bungee.event.EventPriority;
import net.md_5.bungee.protocol.packet.PluginMessage;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Pair;
@@ -140,7 +139,7 @@ public class BungeeServerHandler implements Listener {
int protocolId = ProtocolDetectorService.getProtocolId(serverName);
if (protocolId <= ProtocolVersion.v1_8.getId()) { // 1.8 doesn't have BossBar packet
if (protocolId <= ProtocolVersion.v1_8.getVersion()) { // 1.8 doesn't have BossBar packet
if (storage.getBossbar() != null) {
// TODO: Verify whether this packet needs to be sent when 1.8 -> 1.9 protocol isn't present in the pipeline
// This ensures we can encode it properly as only the 1.9 protocol is currently implemented.
@@ -182,7 +181,7 @@ public class BungeeServerHandler implements Listener {
for (Object message : (List) relayMessages) {
PluginMessage plMsg = (PluginMessage) message;
String channel = plMsg.getTag();
int id1_13 = ProtocolVersion.v1_13.getId();
int id1_13 = ProtocolVersion.v1_13.getVersion();
if (previousServerProtocol != -1) {
String oldChannel = channel;
if (previousServerProtocol < id1_13 && protocolId >= id1_13) {
@@ -47,7 +47,7 @@ public class BungeeViaConfig extends AbstractViaConfig {
if (entry.getValue() instanceof String) {
ProtocolVersion found = ProtocolVersion.getClosest((String) entry.getValue());
if (found != null) {
servers.put(entry.getKey(), found.getId());
servers.put(entry.getKey(), found.getVersion());
} else {
servers.remove(entry.getKey()); // Remove!
}
@@ -45,7 +45,7 @@ public class BungeeViaLoader implements ViaPlatformLoader {
registerListener(new UpdateListener());
registerListener(new BungeeServerHandler());
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getId()) {
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getVersion()) {
registerListener(new ElytraPatch());
}
@@ -53,7 +53,7 @@ public class BungeeViaLoader implements ViaPlatformLoader {
Via.getManager().getProviders().use(VersionProvider.class, new BungeeVersionProvider());
Via.getManager().getProviders().use(EntityIdProvider.class, new BungeeEntityIdProvider());
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getId()) {
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getVersion()) {
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BungeeMovementTransmitter());
Via.getManager().getProviders().use(BossBarProvider.class, new BungeeBossBarProvider());
Via.getManager().getProviders().use(MainHandProvider.class, new BungeeMainHandProvider());
+1 -9
View File
@@ -5,21 +5,13 @@
<parent>
<artifactId>viaversion-parent</artifactId>
<groupId>us.myles</groupId>
<version>3.1.1</version>
<version>3.2.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>viaversion-common</artifactId>
<dependencies>
<!-- Snake YAML -->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.18</version>
<scope>compile</scope> <!-- Velocity doesn't have snakeyaml -->
</dependency>
<!-- FastUtil for performance increases -->
<dependency>
<groupId>it.unimi.dsi</groupId>
@@ -1,11 +1,11 @@
package us.myles.ViaVersion;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import us.myles.ViaVersion.api.ViaVersionConfig;
import us.myles.ViaVersion.util.Config;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
public abstract class AbstractViaConfig extends Config implements ViaVersionConfig {
@@ -35,7 +35,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
private boolean autoTeam;
private boolean forceJsonTransform;
private boolean nbtArrayFix;
private Set<Integer> blockedProtocols;
private IntSet blockedProtocols;
private String blockedDisconnectMessage;
private String reloadDisconnectMessage;
private boolean suppressConversionWarnings;
@@ -93,7 +93,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
autoTeam = getBoolean("auto-team", true);
forceJsonTransform = getBoolean("force-json-transform", false);
nbtArrayFix = getBoolean("chat-nbt-fix", true);
blockedProtocols = new HashSet<>(getIntegerList("block-protocols"));
blockedProtocols = new IntOpenHashSet(getIntegerList("block-protocols"));
blockedDisconnectMessage = getString("block-disconnect-msg", "You are using an unsupported Minecraft version!");
reloadDisconnectMessage = getString("reload-disconnect-msg", "Server reload, please rejoin!");
minimizeCooldown = getBoolean("minimize-cooldown", true);
@@ -120,6 +120,12 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
return checkForUpdates;
}
@Override
public void setCheckForUpdates(boolean checkForUpdates) {
this.checkForUpdates = checkForUpdates;
set("checkforupdates", checkForUpdates);
}
@Override
public boolean isPreventCollision() {
return preventCollision;
@@ -257,7 +263,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
}
@Override
public Set<Integer> getBlockedProtocols() {
public IntSet getBlockedProtocols() {
return blockedProtocols;
}
@@ -83,7 +83,7 @@ public class ViaManager {
public void onServerLoaded() {
// Load Server Protocol
try {
ProtocolRegistry.SERVER_PROTOCOL = injector.getServerProtocolVersion();
ProtocolRegistry.SERVER_PROTOCOL = ProtocolVersion.getProtocol(injector.getServerProtocolVersion()).getVersion();
} catch (Exception e) {
platform.getLogger().severe("ViaVersion failed to get the server protocol!");
e.printStackTrace();
@@ -91,12 +91,15 @@ public class ViaManager {
// Check if there are any pipes to this version
if (ProtocolRegistry.SERVER_PROTOCOL != -1) {
platform.getLogger().info("ViaVersion detected server version: " + ProtocolVersion.getProtocol(ProtocolRegistry.SERVER_PROTOCOL));
if (!ProtocolRegistry.isWorkingPipe()) {
if (!ProtocolRegistry.isWorkingPipe() && !platform.isProxy()) {
platform.getLogger().warning("ViaVersion does not have any compatible versions for this server version!");
platform.getLogger().warning("Please remember that ViaVersion only adds support for versions newer than the server version.");
platform.getLogger().warning("If you need support for older versions you may need to use one or more ViaVersion addons too.");
platform.getLogger().warning("In that case please read the ViaVersion resource page carefully or use https://jo0001.github.io/ViaSetup");
platform.getLogger().warning("and if you're still unsure, feel free to join our Discord-Server for further assistance.");
} else if (ProtocolRegistry.SERVER_PROTOCOL == ProtocolVersion.v1_8.getVersion() && !platform.isProxy()) {
platform.getLogger().warning("This version of Minecraft is over half a decade old and support for it will be fully dropped eventually. "
+ "Please upgrade to a newer version to avoid encountering bugs and stability issues that have long been fixed.");
}
}
// Load Listeners / Tasks
@@ -111,12 +114,12 @@ public class ViaManager {
mappingLoadingTask = null;
}
}, 10L);
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getId()) {
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_9.getVersion()) {
if (Via.getConfig().isSimulatePlayerTick()) {
Via.getPlatform().runRepeatingSync(new ViaIdleThread(), 1L);
}
}
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_13.getId()) {
if (ProtocolRegistry.SERVER_PROTOCOL < ProtocolVersion.v1_13.getVersion()) {
if (Via.getConfig().get1_13TabCompleteDelay() > 0) {
Via.getPlatform().runRepeatingSync(new TabCompleteThread(), 1L);
}
@@ -16,13 +16,13 @@ import us.myles.ViaVersion.util.PipelineUtil;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
public class PacketWrapper {
public static final int PASSTHROUGH_ID = 1000;
private static final Protocol[] PROTOCOL_ARRAY = new Protocol[0];
private final ByteBuf inputBuffer;
private final UserConnection userConnection;
@@ -317,30 +317,33 @@ public class PacketWrapper {
* @throws Exception if it fails to write
*/
private ByteBuf constructPacket(Class<? extends Protocol> packetProtocol, boolean skipCurrentPipeline, Direction direction) throws Exception {
// Apply current pipeline
List<Protocol> protocols = new ArrayList<>(user().getProtocolInfo().getPipeline().pipes());
if (direction == Direction.OUTGOING) {
// Other way if outgoing
Collections.reverse(protocols);
}
// Apply current pipeline - for outgoing protocol, the collection will be reversed in the apply method
Protocol[] protocols = user().getProtocolInfo().getPipeline().pipes().toArray(PROTOCOL_ARRAY);
boolean reverse = direction == Direction.OUTGOING;
int index = -1;
for (int i = 0; i < protocols.size(); i++) {
if (protocols.get(i).getClass().equals(packetProtocol)) {
index = skipCurrentPipeline ? (i + 1) : (i);
for (int i = 0; i < protocols.length; i++) {
if (protocols[i].getClass() == packetProtocol) {
index = i;
break;
}
}
if (index == -1) throw new NoSuchElementException(packetProtocol.getCanonicalName());
if (index == -1) {
// The given protocol is not in the pipeline
throw new NoSuchElementException(packetProtocol.getCanonicalName());
}
if (skipCurrentPipeline) {
index = reverse ? index - 1 : index + 1;
}
// Reset reader before we start
resetReader();
// Apply other protocols
apply(direction, user().getProtocolInfo().getState(), index, protocols);
// Send
apply(direction, user().getProtocolInfo().getState(), index, protocols, reverse);
ByteBuf output = inputBuffer == null ? user().getChannel().alloc().buffer() : inputBuffer.alloc().buffer();
writeToBuffer(output);
return output;
}
@@ -417,22 +420,41 @@ public class PacketWrapper {
}
/**
* Applies a pipeline from an index to the wrapper
* Applies a pipeline from an index to the wrapper.
*
* @param direction The direction
* @param state The state
* @param index The index to start from
* @param pipeline The pipeline
* @param direction protocol direction
* @param state protocol state
* @param index index to start from, will be reversed depending on the reverse parameter
* @param pipeline protocol pipeline
* @param reverse whether the array should be looped in reverse, will also reverse the given index
* @return The current packetwrapper
* @throws Exception If it fails to transform a packet, exception will be thrown
*/
public PacketWrapper apply(Direction direction, State state, int index, List<Protocol> pipeline) throws Exception {
for (int i = index; i < pipeline.size(); i++) { // Copy to prevent from removal.
pipeline.get(i).transform(direction, state, this);
// Reset the reader for the packetWrapper (So it can be recycled across packets)
resetReader();
}
public PacketWrapper apply(Direction direction, State state, int index, List<Protocol> pipeline, boolean reverse) throws Exception {
Protocol[] array = pipeline.toArray(PROTOCOL_ARRAY);
return apply(direction, state, reverse ? array.length - 1 : index, array, reverse); // Copy to prevent from removal
}
/**
* @see #apply(Direction, State, int, List, boolean)
*/
public PacketWrapper apply(Direction direction, State state, int index, List<Protocol> pipeline) throws Exception {
return apply(direction, state, index, pipeline.toArray(PROTOCOL_ARRAY), false);
}
private PacketWrapper apply(Direction direction, State state, int index, Protocol[] pipeline, boolean reverse) throws Exception {
// Reset the reader after every transformation for the packetWrapper, so it can be recycled across packets
if (reverse) {
for (int i = index; i >= 0; i--) {
pipeline[i].transform(direction, state, this);
resetReader();
}
} else {
for (int i = index; i < pipeline.length; i++) {
pipeline[i].transform(direction, state, this);
resetReader();
}
}
return this;
}
@@ -1,6 +1,6 @@
package us.myles.ViaVersion.api;
import java.util.Set;
import it.unimi.dsi.fastutil.ints.IntSet;
public interface ViaVersionConfig {
@@ -11,6 +11,14 @@ public interface ViaVersionConfig {
*/
boolean isCheckForUpdates();
/**
* Sets whether to check for updates. This updates the internally cached value
* as well as the config, but does not save the config to disk.
*
* @param checkForUpdates true to check for updates on server start and joins
*/
void setCheckForUpdates(boolean checkForUpdates);
/**
* Get if collision preventing for players is enabled
*
@@ -213,7 +221,7 @@ public interface ViaVersionConfig {
*
* @return An Integer list
*/
Set<Integer> getBlockedProtocols();
IntSet getBlockedProtocols();
/**
* Get the custom disconnect message
@@ -0,0 +1,145 @@
package us.myles.ViaVersion.api.data;
import com.google.gson.JsonObject;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.util.Int2IntBiMap;
public class MappingData {
protected final String oldVersion;
protected final String newVersion;
protected final boolean hasDiffFile;
protected Int2IntBiMap itemMappings;
protected ParticleMappings particleMappings;
protected Mappings blockMappings;
protected Mappings blockStateMappings;
protected Mappings soundMappings;
protected Mappings statisticsMappings;
protected boolean loadItems = true;
public MappingData(String oldVersion, String newVersion) {
this(oldVersion, newVersion, false);
}
public MappingData(String oldVersion, String newVersion, boolean hasDiffFile) {
this.oldVersion = oldVersion;
this.newVersion = newVersion;
this.hasDiffFile = hasDiffFile;
}
public void load() {
Via.getPlatform().getLogger().info("Loading " + oldVersion + " -> " + newVersion + " mappings...");
JsonObject diffmapping = hasDiffFile ? loadDiffFile() : null;
JsonObject oldMappings = MappingDataLoader.loadData("mapping-" + oldVersion + ".json", true);
JsonObject newMappings = MappingDataLoader.loadData("mapping-" + newVersion + ".json", true);
blockMappings = loadFromObject(oldMappings, newMappings, diffmapping, "blocks");
blockStateMappings = loadFromObject(oldMappings, newMappings, diffmapping, "blockstates");
soundMappings = loadFromArray(oldMappings, newMappings, diffmapping, "sounds");
statisticsMappings = loadFromArray(oldMappings, newMappings, diffmapping, "statistics");
Mappings particles = loadFromArray(oldMappings, newMappings, diffmapping, "particles");
if (particles != null) {
particleMappings = new ParticleMappings(oldMappings.getAsJsonArray("particles"), particles);
}
if (loadItems && newMappings.has("items")) {
itemMappings = new Int2IntBiMap();
itemMappings.defaultReturnValue(-1);
MappingDataLoader.mapIdentifiers(itemMappings, oldMappings.getAsJsonObject("items"), newMappings.getAsJsonObject("items"),
diffmapping != null ? diffmapping.getAsJsonObject("items") : null);
}
loadExtras(oldMappings, newMappings, diffmapping);
}
public int getNewBlockStateId(int id) {
return checkValidity(id, blockStateMappings.getNewId(id), "blockstate");
}
public int getNewBlockId(int id) {
return checkValidity(id, blockMappings.getNewId(id), "block");
}
public int getNewItemId(int id) {
return checkValidity(id, itemMappings.get(id), "item");
}
public int getOldItemId(int id) {
int oldId = itemMappings.inverse().get(id);
// Remap new items to stone
return oldId != -1 ? oldId : 1;
}
public int getNewParticleId(int id) {
return checkValidity(id, particleMappings.getMappings().getNewId(id), "particles");
}
@Nullable
public Int2IntBiMap getItemMappings() {
return itemMappings;
}
@Nullable
public ParticleMappings getParticleMappings() {
return particleMappings;
}
@Nullable
public Mappings getBlockMappings() {
return blockMappings;
}
@Nullable
public Mappings getBlockStateMappings() {
return blockStateMappings;
}
@Nullable
public Mappings getSoundMappings() {
return soundMappings;
}
@Nullable
public Mappings getStatisticsMappings() {
return statisticsMappings;
}
@Nullable
protected Mappings loadFromArray(JsonObject oldMappings, JsonObject newMappings, @Nullable JsonObject diffMappings, String key) {
if (!oldMappings.has(key) || !newMappings.has(key)) return null;
JsonObject diff = diffMappings != null ? diffMappings.getAsJsonObject(key) : null;
return new Mappings(oldMappings.getAsJsonArray(key), newMappings.getAsJsonArray(key), diff);
}
@Nullable
protected Mappings loadFromObject(JsonObject oldMappings, JsonObject newMappings, @Nullable JsonObject diffMappings, String key) {
if (!oldMappings.has(key) || !newMappings.has(key)) return null;
JsonObject diff = diffMappings != null ? diffMappings.getAsJsonObject(key) : null;
return new Mappings(oldMappings.getAsJsonObject(key), newMappings.getAsJsonObject(key), diff);
}
protected JsonObject loadDiffFile() {
return MappingDataLoader.loadData("mappingdiff-" + oldVersion + "to" + newVersion + ".json");
}
protected int checkValidity(int id, int mappedId, String type) {
if (mappedId == -1) {
Via.getPlatform().getLogger().warning(String.format("Missing %s %s for %s %s %d", newVersion, type, oldVersion, type, id));
return 0;
}
return mappedId;
}
/**
* To be overridden.
*
* @param oldMappings old mappings
* @param newMappings new mappings
* @param diffMappings diff mappings if present
*/
protected void loadExtras(JsonObject oldMappings, JsonObject newMappings, @Nullable JsonObject diffMappings) {
}
}
@@ -5,9 +5,12 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonIOException;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.util.GsonUtil;
import us.myles.ViaVersion.util.Int2IntBiMap;
import java.io.File;
import java.io.FileReader;
@@ -48,6 +51,7 @@ public class MappingDataLoader {
/**
* Loads the file from the plugin folder if present, else from the bundled resources.
*/
@Nullable
public static JsonObject loadFromDataDir(String name) {
File file = new File(Via.getPlatform().getDataFolder(), name);
if (!file.exists()) return loadData(name);
@@ -68,6 +72,7 @@ public class MappingDataLoader {
/**
* Loads the file from the bundled resources. Uses the cache if enabled.
*/
@Nullable
public static JsonObject loadData(String name) {
return loadData(name, false);
}
@@ -77,6 +82,7 @@ public class MappingDataLoader {
*
* @param cacheIfEnabled whether loaded files should be cached
*/
@Nullable
public static JsonObject loadData(String name, boolean cacheIfEnabled) {
if (cacheJsonMappings) {
JsonObject cached = MAPPINGS_CACHE.get(name);
@@ -86,6 +92,8 @@ public class MappingDataLoader {
}
InputStream stream = getResource(name);
if (stream == null) return null;
InputStreamReader reader = new InputStreamReader(stream);
try {
JsonObject object = GsonUtil.getGson().fromJson(reader, JsonObject.class);
@@ -102,15 +110,12 @@ public class MappingDataLoader {
}
}
public static void mapIdentifiers(Map<Integer, Integer> output, JsonObject oldIdentifiers, JsonObject newIdentifiers) {
mapIdentifiers(output, oldIdentifiers, newIdentifiers, null);
}
public static void mapIdentifiers(Map<Integer, Integer> output, JsonObject oldIdentifiers, JsonObject newIdentifiers, JsonObject diffIdentifiers) {
public static void mapIdentifiers(Int2IntBiMap output, JsonObject oldIdentifiers, JsonObject newIdentifiers, @Nullable JsonObject diffIdentifiers) {
Object2IntMap<String> newIdentifierMap = MappingDataLoader.indexedObjectToMap(newIdentifiers);
for (Map.Entry<String, JsonElement> entry : oldIdentifiers.entrySet()) {
Map.Entry<String, JsonElement> value = mapIdentifierEntry(entry, oldIdentifiers, newIdentifiers, diffIdentifiers);
if (value != null) {
output.put(Integer.parseInt(entry.getKey()), Integer.parseInt(value.getKey()));
int value = mapIdentifierEntry(entry, newIdentifierMap, diffIdentifiers);
if (value != -1) {
output.put(Integer.parseInt(entry.getKey()), value);
}
}
}
@@ -119,31 +124,31 @@ public class MappingDataLoader {
MappingDataLoader.mapIdentifiers(output, oldIdentifiers, newIdentifiers, null);
}
public static void mapIdentifiers(short[] output, JsonObject oldIdentifiers, JsonObject newIdentifiers, JsonObject diffIdentifiers) {
public static void mapIdentifiers(short[] output, JsonObject oldIdentifiers, JsonObject newIdentifiers, @Nullable JsonObject diffIdentifiers) {
Object2IntMap newIdentifierMap = MappingDataLoader.indexedObjectToMap(newIdentifiers);
for (Map.Entry<String, JsonElement> entry : oldIdentifiers.entrySet()) {
Map.Entry<String, JsonElement> value = mapIdentifierEntry(entry, oldIdentifiers, newIdentifiers, diffIdentifiers);
if (value != null) {
output[Integer.parseInt(entry.getKey())] = Short.parseShort(value.getKey());
int value = mapIdentifierEntry(entry, newIdentifierMap, diffIdentifiers);
if (value != -1) {
output[Integer.parseInt(entry.getKey())] = (short) value;
}
}
}
@Nullable
private static Map.Entry<String, JsonElement> mapIdentifierEntry(Map.Entry<String, JsonElement> entry, JsonObject oldIdentifiers, JsonObject newIdentifiers, JsonObject diffIdentifiers) {
Map.Entry<String, JsonElement> value = findValue(newIdentifiers, entry.getValue().getAsString());
if (value == null) {
private static int mapIdentifierEntry(Map.Entry<String, JsonElement> entry, Object2IntMap newIdentifierMap, @Nullable JsonObject diffIdentifiers) {
int value = newIdentifierMap.getInt(entry.getValue().getAsString());
if (value == -1) {
// Search in diff mappings
if (diffIdentifiers != null) {
JsonElement diffElement = diffIdentifiers.get(entry.getKey());
if (diffElement != null) {
value = findValue(newIdentifiers, diffElement.getAsString());
value = newIdentifierMap.getInt(diffElement.getAsString());
}
}
if (value == null) {
if (value == -1) {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
Via.getPlatform().getLogger().warning("No key for " + entry.getValue() + " :( ");
}
return null;
return -1;
}
}
return value;
@@ -153,61 +158,60 @@ public class MappingDataLoader {
mapIdentifiers(output, oldIdentifiers, newIdentifiers, null, warnOnMissing);
}
public static void mapIdentifiers(short[] output, JsonArray oldIdentifiers, JsonArray newIdentifiers, JsonObject diffIdentifiers, boolean warnOnMissing) {
public static void mapIdentifiers(short[] output, JsonArray oldIdentifiers, JsonArray newIdentifiers, @Nullable JsonObject diffIdentifiers, boolean warnOnMissing) {
Object2IntMap<String> newIdentifierMap = MappingDataLoader.arrayToMap(newIdentifiers);
for (int i = 0; i < oldIdentifiers.size(); i++) {
JsonElement value = oldIdentifiers.get(i);
Integer index = findIndex(newIdentifiers, value.getAsString());
if (index == null) {
JsonElement oldIdentifier = oldIdentifiers.get(i);
int mappedId = newIdentifierMap.getInt(oldIdentifier.getAsString());
if (mappedId == -1) {
// Search in diff mappings
if (diffIdentifiers != null) {
JsonElement diffElement = diffIdentifiers.get(value.getAsString());
JsonElement diffElement = diffIdentifiers.get(oldIdentifier.getAsString());
if (diffElement != null) {
index = findIndex(newIdentifiers, diffElement.getAsString());
String mappedName = diffElement.getAsString();
if (mappedName.isEmpty()) continue; // "empty" remaps
mappedId = newIdentifierMap.getInt(mappedName);
}
}
if (index == null) {
if (mappedId == -1) {
if (warnOnMissing && !Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
Via.getPlatform().getLogger().warning("No key for " + value + " :( ");
Via.getPlatform().getLogger().warning("No key for " + oldIdentifier + " :( ");
}
continue;
}
}
output[i] = index.shortValue();
output[i] = (short) mappedId;
}
}
public static void mapIdentifiers(byte[] output, JsonObject oldIdentifiers, JsonObject newIdentifiers) {
for (Map.Entry<String, JsonElement> entry : oldIdentifiers.entrySet()) {
Map.Entry<String, JsonElement> value = MappingDataLoader.findValue(newIdentifiers, entry.getValue().getAsString());
if (value == null) {
Via.getPlatform().getLogger().warning("No key for " + entry.getValue() + " :( ");
continue;
}
output[Integer.parseInt(entry.getKey())] = Byte.parseByte(value.getKey());
}
}
@Nullable
public static Map.Entry<String, JsonElement> findValue(JsonObject object, String needle) {
/**
* @param object json object
* @return map with indexes hashed by their id value
*/
public static Object2IntMap<String> indexedObjectToMap(JsonObject object) {
Object2IntMap<String> map = new Object2IntOpenHashMap<>(object.size(), 1F);
map.defaultReturnValue(-1);
for (Map.Entry<String, JsonElement> entry : object.entrySet()) {
String value = entry.getValue().getAsString();
if (value.equals(needle)) {
return entry;
}
map.put(entry.getValue().getAsString(), Integer.parseInt(entry.getKey()));
}
return null;
return map;
}
/**
* @param array json array
* @return map with indexes hashed by their id value
*/
public static Object2IntMap<String> arrayToMap(JsonArray array) {
Object2IntMap<String> map = new Object2IntOpenHashMap<>(array.size(), 1F);
map.defaultReturnValue(-1);
for (int i = 0; i < array.size(); i++) {
map.put(array.get(i).getAsString(), i);
}
return map;
}
@Nullable
public static Integer findIndex(JsonArray array, String value) {
for (int i = 0; i < array.size(); i++) {
JsonElement v = array.get(i);
if (v.getAsString().equals(value)) {
return i;
}
}
return null;
}
public static InputStream getResource(String name) {
return MappingDataLoader.class.getClassLoader().getResourceAsStream("assets/viaversion/data/" + name);
}
@@ -2,13 +2,14 @@ package us.myles.ViaVersion.api.data;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
public class Mappings {
protected final short[] oldToNew;
protected Mappings(short[] oldToNew) {
public Mappings(short[] oldToNew) {
this.oldToNew = oldToNew;
}
@@ -21,13 +22,13 @@ public class Mappings {
* @param newMapping mappings to map to
* @param diffMapping extra mappings that will be used/scanned when an entry cannot be found
*/
public Mappings(int size, JsonObject oldMapping, JsonObject newMapping, JsonObject diffMapping) {
public Mappings(int size, JsonObject oldMapping, JsonObject newMapping, @Nullable JsonObject diffMapping) {
oldToNew = new short[size];
Arrays.fill(oldToNew, (short) -1);
MappingDataLoader.mapIdentifiers(oldToNew, oldMapping, newMapping, diffMapping);
}
public Mappings(JsonObject oldMapping, JsonObject newMapping, JsonObject diffMapping) {
public Mappings(JsonObject oldMapping, JsonObject newMapping, @Nullable JsonObject diffMapping) {
this(oldMapping.entrySet().size(), oldMapping, newMapping, diffMapping);
}
@@ -86,4 +87,8 @@ public class Mappings {
public int getNewId(int old) {
return old >= 0 && old < oldToNew.length ? oldToNew[old] : -1;
}
public short[] getOldToNew() {
return oldToNew;
}
}
@@ -0,0 +1,36 @@
package us.myles.ViaVersion.api.data;
import com.google.gson.JsonArray;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
public class ParticleMappings {
private final Mappings mappings;
private final int blockId;
private final int fallingDustId;
private final int itemId;
public ParticleMappings(JsonArray oldMappings, Mappings mappings) {
this.mappings = mappings;
Object2IntMap<String> map = MappingDataLoader.arrayToMap(oldMappings);
blockId = map.getInt("block");
fallingDustId = map.getInt("falling_dust");
itemId = map.getInt("item");
}
public Mappings getMappings() {
return mappings;
}
public int getBlockId() {
return blockId;
}
public int getFallingDustId() {
return fallingDustId;
}
public int getItemId() {
return itemId;
}
}
@@ -3,7 +3,6 @@ package us.myles.ViaVersion.api.data;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import net.md_5.bungee.api.ChatColor;
import org.jetbrains.annotations.Nullable;
@@ -18,7 +17,6 @@ import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.util.PipelineUtil;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
@@ -27,8 +25,9 @@ public class UserConnection {
private static final AtomicLong IDS = new AtomicLong();
private final long id = IDS.incrementAndGet();
private final Channel channel;
private ProtocolInfo protocolInfo;
private final boolean clientSide;
Map<Class, StoredObject> storedObjects = new ConcurrentHashMap<>();
private ProtocolInfo protocolInfo;
private boolean active = true;
private boolean pendingDisconnect;
private Object lastPacket;
@@ -42,8 +41,23 @@ public class UserConnection {
private int secondsObserved;
private int warnings;
public UserConnection(@Nullable Channel channel) {
/**
* Creates an UserConnection. When it's a client-side connection, some method behaviors are modified.
*
* @param channel netty channel.
* @param clientSide true if it's a client-side connection
*/
public UserConnection(@Nullable Channel channel, boolean clientSide) {
this.channel = channel;
this.clientSide = clientSide;
}
/**
* @param channel
* @see #UserConnection(Channel, boolean)
*/
public UserConnection(@Nullable Channel channel) {
this(channel, false);
}
/**
@@ -91,12 +105,24 @@ public class UserConnection {
* @param packet The raw packet to send
* @param currentThread Should it run in the same thread
*/
public void sendRawPacket(ByteBuf packet, boolean currentThread) {
ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName());
if (currentThread) {
channel.pipeline().context(handler).writeAndFlush(packet);
public void sendRawPacket(final ByteBuf packet, boolean currentThread) {
Runnable act;
if (clientSide) {
// We'll just assume that Via decoder isn't wrapping the original decoder
act = () -> getChannel().pipeline()
.context(Via.getManager().getInjector().getDecoderName()).fireChannelRead(packet);
} else {
channel.eventLoop().submit(() -> channel.pipeline().context(handler).writeAndFlush(packet));
act = () -> channel.pipeline().context(Via.getManager().getInjector().getEncoderName()).writeAndFlush(packet);
}
if (currentThread) {
act.run();
} else {
try {
channel.eventLoop().submit(act);
} catch (Throwable e) {
packet.release(); // Couldn't schedule
e.printStackTrace();
}
}
}
@@ -106,9 +132,22 @@ public class UserConnection {
* @param packet The raw packet to send
* @return ChannelFuture of the packet being sent
*/
public ChannelFuture sendRawPacketFuture(ByteBuf packet) {
ChannelHandler handler = channel.pipeline().get(Via.getManager().getInjector().getEncoderName());
return channel.pipeline().context(handler).writeAndFlush(packet);
public ChannelFuture sendRawPacketFuture(final ByteBuf packet) {
if (clientSide) {
return sendRawPacketFutureClientSide(packet);
} else {
return sendRawPacketFutureServerSide(packet);
}
}
private ChannelFuture sendRawPacketFutureServerSide(final ByteBuf packet) {
return channel.pipeline().context(Via.getManager().getInjector().getEncoderName()).writeAndFlush(packet);
}
private ChannelFuture sendRawPacketFutureClientSide(final ByteBuf packet) {
// Assume that decoder isn't wrapping
getChannel().pipeline().context(Via.getManager().getInjector().getDecoderName()).fireChannelRead(packet);
return getChannel().newSucceededFuture();
}
/**
@@ -156,6 +195,7 @@ public class UserConnection {
* @see #incrementReceived()
*/
public boolean exceedsMaxPPS() {
if (clientSide) return false; // Don't apply PPS limiting for client-side
ViaVersionConfig conf = Via.getConfig();
// Max PPS Checker
if (conf.getMaxPPS() > 0) {
@@ -195,14 +235,8 @@ public class UserConnection {
if (!channel.isOpen() || pendingDisconnect) return;
pendingDisconnect = true;
UUID uuid = protocolInfo.getUuid();
if (uuid == null) {
channel.close(); // Just disconnect, we don't know what the connection is
return;
}
Via.getPlatform().runSync(() -> {
if (!Via.getPlatform().kickPlayer(uuid, ChatColor.translateAlternateColorCodes('&', reason))) {
if (!Via.getPlatform().disconnect(this, ChatColor.translateAlternateColorCodes('&', reason))) {
channel.close(); // =)
}
});
@@ -214,9 +248,20 @@ public class UserConnection {
* @param packet Raw packet to be sent
* @param currentThread If {@code true} executes immediately, {@code false} submits a task to EventLoop
*/
public void sendRawPacketToServer(ByteBuf packet, boolean currentThread) {
ByteBuf buf = packet.alloc().buffer();
public void sendRawPacketToServer(final ByteBuf packet, boolean currentThread) {
if (clientSide) {
sendRawPacketToServerClientSide(packet, currentThread);
} else {
sendRawPacketToServerServerSide(packet, currentThread);
}
}
private void sendRawPacketToServerServerSide(final ByteBuf packet, boolean currentThread) {
final ByteBuf buf = packet.alloc().buffer();
try {
// We'll use passing through because there are some encoder wrappers
ChannelHandlerContext context = PipelineUtil
.getPreviousContext(Via.getManager().getInjector().getDecoderName(), channel.pipeline());
try {
Type.VAR_INT.writePrimitive(buf, PacketWrapper.PASSTHROUGH_ID);
} catch (Exception e) {
@@ -224,23 +269,18 @@ public class UserConnection {
Via.getPlatform().getLogger().warning("Type.VAR_INT.write thrown an exception: " + e);
}
buf.writeBytes(packet);
ChannelHandlerContext context = PipelineUtil
.getPreviousContext(Via.getManager().getInjector().getDecoderName(), channel.pipeline());
if (currentThread) {
Runnable act = () -> {
if (context != null) {
context.fireChannelRead(buf);
} else {
channel.pipeline().fireChannelRead(buf);
}
};
if (currentThread) {
act.run();
} else {
try {
channel.eventLoop().submit(() -> {
if (context != null) {
context.fireChannelRead(buf);
} else {
channel.pipeline().fireChannelRead(buf);
}
});
channel.eventLoop().submit(act);
} catch (Throwable t) {
// Couldn't schedule
buf.release();
@@ -252,6 +292,21 @@ public class UserConnection {
}
}
private void sendRawPacketToServerClientSide(final ByteBuf packet, boolean currentThread) {
Runnable act = () -> getChannel().pipeline()
.context(Via.getManager().getInjector().getEncoderName()).writeAndFlush(packet);
if (currentThread) {
act.run();
} else {
try {
getChannel().eventLoop().submit(act);
} catch (Throwable e) {
e.printStackTrace();
packet.release(); // Couldn't schedule
}
}
}
/**
* Sends a raw packet to the server. It will submit a task to EventLoop.
*
@@ -262,11 +317,24 @@ public class UserConnection {
}
/**
* Monitors serverbound packets.
* Monitors incoming packets
*
* @return false if this packet should be cancelled
*/
public boolean checkIncomingPacket() {
if (clientSide) {
return checkClientBound();
} else {
return checkServerBound();
}
}
private boolean checkClientBound() {
incrementSent();
return true;
}
private boolean checkServerBound() {
// Ignore if pending disconnect
if (pendingDisconnect) return false;
// Increment received + Check PPS
@@ -274,10 +342,16 @@ public class UserConnection {
}
/**
* Monitors clientbound packets.
* Monitors outgoing packets
*
* @return false if this packet should be cancelled
*/
public void checkOutgoingPacket() {
incrementSent();
public boolean checkOutgoingPacket() {
if (clientSide) {
return checkServerBound();
} else {
return checkClientBound();
}
}
/**
@@ -290,7 +364,8 @@ public class UserConnection {
}
/**
* Transforms the clientbound packet contained in an outgoing ByteBuf.
* Transforms the outgoing packet contained in ByteBuf. When clientSide is true, this packet is considered
* serverbound.
*
* @param buf ByteBuf with packet id and packet contents
* @param cancelSupplier Function called with original CancelException for generating the Exception used when
@@ -301,11 +376,12 @@ public class UserConnection {
*/
public void transformOutgoing(ByteBuf buf, Function<Throwable, Exception> cancelSupplier) throws Exception {
if (!buf.isReadable()) return;
transform(buf, Direction.OUTGOING, cancelSupplier);
transform(buf, clientSide ? Direction.INCOMING : Direction.OUTGOING, cancelSupplier);
}
/**
* Transforms the serverbound packet contained in an incoming ByteBuf.
* Transforms the incoming packet contained in ByteBuf. When clientSide is true, this packet is considered
* clientbound
*
* @param buf ByteBuf with packet id and packet contents
* @param cancelSupplier Function called with original CancelException for generating the Exception used when
@@ -316,7 +392,7 @@ public class UserConnection {
*/
public void transformIncoming(ByteBuf buf, Function<Throwable, Exception> cancelSupplier) throws Exception {
if (!buf.isReadable()) return;
transform(buf, Direction.INCOMING, cancelSupplier);
transform(buf, clientSide ? Direction.OUTGOING : Direction.INCOMING, cancelSupplier);
}
private void transform(ByteBuf buf, Direction direction, Function<Throwable, Exception> cancelSupplier) throws Exception {
@@ -459,4 +535,12 @@ public class UserConnection {
public int hashCode() {
return Long.hashCode(id);
}
public boolean isClientSide() {
return clientSide;
}
public boolean shouldApplyBlockProtocol() {
return !clientSide; // Don't apply protocol blocking on client-side
}
}
@@ -36,7 +36,7 @@ public class BlockChangeRecord1_16_2 implements BlockChangeRecord {
@Override
public short getY(int chunkSectionY) {
Preconditions.checkArgument(chunkSectionY >= 0 && chunkSectionY < 16);
Preconditions.checkArgument(chunkSectionY >= 0 && chunkSectionY < 16, "Invalid chunkSectionY: " + chunkSectionY);
return (short) ((chunkSectionY << 4) + sectionY);
}
@@ -1,13 +1,12 @@
package us.myles.ViaVersion.api.minecraft.chunks;
import io.netty.buffer.ByteBuf;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ChunkSection {
/**
@@ -18,8 +17,8 @@ public class ChunkSection {
* Length of the sky and block light nibble arrays.
*/
public static final int LIGHT_LENGTH = 16 * 16 * 16 / 2; // size * size * size / 2 (nibble bit count)
private final List<Integer> palette = new ArrayList<>();
private final Map<Integer, Integer> inversePalette = new HashMap<>();
private final IntList palette;
private final Int2IntMap inversePalette;
private final int[] blocks;
private NibbleArray blockLight;
private NibbleArray skyLight;
@@ -28,7 +27,19 @@ public class ChunkSection {
public ChunkSection() {
this.blocks = new int[SIZE];
this.blockLight = new NibbleArray(SIZE);
addPaletteEntry(0);
palette = new IntArrayList();
inversePalette = new Int2IntOpenHashMap();
inversePalette.defaultReturnValue(-1);
}
public ChunkSection(int expectedPaletteLength) {
this.blocks = new int[SIZE];
this.blockLight = new NibbleArray(SIZE);
// Pre-size the palette array/map
palette = new IntArrayList(expectedPaletteLength);
inversePalette = new Int2IntOpenHashMap(expectedPaletteLength);
inversePalette.defaultReturnValue(-1);
}
/**
@@ -59,12 +70,12 @@ public class ChunkSection {
public int getFlatBlock(int x, int y, int z) {
int index = blocks[index(x, y, z)];
return palette.get(index);
return palette.getInt(index);
}
public int getFlatBlock(int idx) {
int index = blocks[idx];
return palette.get(index);
return palette.getInt(index);
}
public void setBlock(int idx, int type, int data) {
@@ -85,18 +96,20 @@ public class ChunkSection {
public int getPaletteEntry(int index) {
if (index < 0 || index >= palette.size()) throw new IndexOutOfBoundsException();
return palette.get(index);
return palette.getInt(index);
}
public void setPaletteEntry(int index, int id) {
if (index < 0 || index >= palette.size()) throw new IndexOutOfBoundsException();
int oldId = palette.set(index, id);
if (oldId == id) return;
inversePalette.put(id, index);
if (inversePalette.get(oldId) == index) {
inversePalette.remove(oldId);
for (int i = 0; i < palette.size(); i++) {
if (palette.get(i) == oldId) {
if (palette.getInt(i) == oldId) {
inversePalette.put(oldId, i);
break;
}
@@ -105,11 +118,14 @@ public class ChunkSection {
}
public void replacePaletteEntry(int oldId, int newId) {
Integer index = inversePalette.remove(oldId);
if (index == null) return;
int index = inversePalette.remove(oldId);
if (index == -1) return;
inversePalette.put(newId, index);
for (int i = 0; i < palette.size(); i++) {
if (palette.get(i) == oldId) palette.set(i, newId);
if (palette.getInt(i) == oldId) {
palette.set(i, newId);
}
}
}
@@ -131,8 +147,8 @@ public class ChunkSection {
* @param id The raw or flat id of the block
*/
public void setFlatBlock(int idx, int id) {
Integer index = inversePalette.get(id);
if (index == null) {
int index = inversePalette.get(id);
if (index == -1) {
index = palette.size();
palette.add(id);
inversePalette.put(id, index);
@@ -46,7 +46,7 @@ public class ViaConnectionManager {
* UUIDs can't be duplicate between frontend connections.
*/
public boolean isFrontEnd(UserConnection conn) {
return true;
return !conn.isClientSide();
}
/**
@@ -1,10 +1,13 @@
package us.myles.ViaVersion.api.platform;
import com.google.gson.JsonObject;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.ViaAPI;
import us.myles.ViaVersion.api.ViaVersionConfig;
import us.myles.ViaVersion.api.command.ViaCommandSender;
import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import java.io.File;
import java.util.UUID;
@@ -16,6 +19,7 @@ import java.util.logging.Logger;
* @param <T> - The player type for the platform, used for API related methods
*/
public interface ViaPlatform<T> {
/**
* Get the logger for this platform
*
@@ -33,10 +37,19 @@ public interface ViaPlatform<T> {
/**
* Get the platform version
*
* @return Platforn version
* @return Platform version
*/
String getPlatformVersion();
/**
* Returns true if the server Via is running on is a proxy server.
*
* @return true if the platform is a proxy
*/
default boolean isProxy() {
return false;
}
/**
* Get the plugin version
*
@@ -111,6 +124,20 @@ public interface ViaPlatform<T> {
*/
boolean kickPlayer(UUID uuid, String message);
/**
* Disconnects an UserConnection for a reason
*
* @param connection The UserConnection
* @param message The message to kick them with
* @return True if it was successful
*/
default boolean disconnect(UserConnection connection, String message) {
if (connection.isClientSide()) return false;
UUID uuid = connection.get(ProtocolInfo.class).getUuid();
if (uuid == null) return false;
return kickPlayer(uuid, message);
}
/**
* Check if the plugin is enabled.
*
@@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingData;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.platform.providers.ViaProviders;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
@@ -36,14 +37,9 @@ public abstract class Protocol<C1 extends ClientboundPacketType, C2 extends Clie
protected final Class<C2> newClientboundPacketEnum;
protected final Class<S1> oldServerboundPacketEnum;
protected final Class<S2> newServerboundPacketEnum;
protected final boolean hasMappingDataToLoad;
protected Protocol() {
this(null, null, null, null, false);
}
protected Protocol(boolean hasMappingDataToLoad) {
this(null, null, null, null, hasMappingDataToLoad);
this(null, null, null, null);
}
/**
@@ -51,21 +47,10 @@ public abstract class Protocol<C1 extends ClientboundPacketType, C2 extends Clie
*/
protected Protocol(@Nullable Class<C1> oldClientboundPacketEnum, @Nullable Class<C2> clientboundPacketEnum,
@Nullable Class<S1> oldServerboundPacketEnum, @Nullable Class<S2> serverboundPacketEnum) {
this(oldClientboundPacketEnum, clientboundPacketEnum, oldServerboundPacketEnum, serverboundPacketEnum, false);
}
/**
* Creates a protocol with automated id mapping if the respective enums are not null.
*
* @param hasMappingDataToLoad whether an async executor should call the {@Link #loadMappingData} method
*/
protected Protocol(@Nullable Class<C1> oldClientboundPacketEnum, @Nullable Class<C2> clientboundPacketEnum,
@Nullable Class<S1> oldServerboundPacketEnum, @Nullable Class<S2> serverboundPacketEnum, boolean hasMappingDataToLoad) {
this.oldClientboundPacketEnum = oldClientboundPacketEnum;
this.newClientboundPacketEnum = clientboundPacketEnum;
this.oldServerboundPacketEnum = oldServerboundPacketEnum;
this.newServerboundPacketEnum = serverboundPacketEnum;
this.hasMappingDataToLoad = hasMappingDataToLoad;
registerPackets();
// Register the rest of the ids with no handlers if necessary
@@ -157,11 +142,19 @@ public abstract class Protocol<C1 extends ClientboundPacketType, C2 extends Clie
}
/**
* Load mapping data for the protocol.
* Loads the mappingdata.
*/
protected final void loadMappingData() {
getMappingData().load();
onMappingDataLoaded();
}
/**
* Called after {@link #loadMappingData()} is called; load extra mapping data for the protocol.
* <p>
* To be overridden if needed.
*/
protected void loadMappingData() {
protected void onMappingDataLoaded() {
}
/**
@@ -387,10 +380,6 @@ public abstract class Protocol<C1 extends ClientboundPacketType, C2 extends Clie
return incoming.containsKey(packet);
}
public boolean hasMappingDataToLoad() {
return hasMappingDataToLoad;
}
/**
* Transform a packet using this protocol
*
@@ -470,6 +459,23 @@ public abstract class Protocol<C1 extends ClientboundPacketType, C2 extends Clie
storedObjects.put(object.getClass(), object);
}
/**
* Returns true if this Protocol's {@link #loadMappingData()} method should be called.
* <p>
* This does *not* necessarily mean that {@link #getMappingData()} is non-null, since this may be
* overriden, depending on special cases.
*
* @return true if this Protocol's {@link #loadMappingData()} method should be called
*/
public boolean hasMappingDataToLoad() {
return getMappingData() != null;
}
@Nullable
public MappingData getMappingData() {
return null; // Let the protocols hold the mappings to still have easy, static singleton access there
}
@Override
public String toString() {
return "Protocol:" + getClass().getSimpleName();
@@ -9,7 +9,6 @@ import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
@@ -19,7 +18,6 @@ public class ProtocolPipeline extends SimpleProtocol {
private UserConnection userConnection;
public ProtocolPipeline(UserConnection userConnection) {
super();
init(userConnection);
}
@@ -72,39 +70,38 @@ public class ProtocolPipeline extends SimpleProtocol {
@Override
public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws Exception {
int originalID = packetWrapper.getId();
List<Protocol> protocols = new ArrayList<>(protocolList);
// Other way if outgoing
if (direction == Direction.OUTGOING)
Collections.reverse(protocols);
// Apply protocols
packetWrapper.apply(direction, state, 0, protocols);
packetWrapper.apply(direction, state, 0, protocolList, direction == Direction.OUTGOING);
super.transform(direction, state, packetWrapper);
if (Via.getManager().isDebug()) {
// Debug packet
int serverProtocol = userConnection.getProtocolInfo().getServerProtocolVersion();
int clientProtocol = userConnection.getProtocolInfo().getProtocolVersion();
ViaPlatform platform = Via.getPlatform();
String actualUsername = packetWrapper.user().getProtocolInfo().getUsername();
String username = actualUsername != null ? actualUsername + " " : "";
platform.getLogger().log(Level.INFO, "{0}{1} {2}: {3} (0x{4}) -> {5} (0x{6}) [{7}] {8}",
new Object[]{
username,
direction,
state,
originalID,
Integer.toHexString(originalID),
packetWrapper.getId(),
Integer.toHexString(packetWrapper.getId()),
Integer.toString(clientProtocol),
packetWrapper
});
logPacket(direction, state, packetWrapper, originalID);
}
}
private void logPacket(Direction direction, State state, PacketWrapper packetWrapper, int originalID) {
// Debug packet
int clientProtocol = userConnection.getProtocolInfo().getProtocolVersion();
ViaPlatform platform = Via.getPlatform();
String actualUsername = packetWrapper.user().getProtocolInfo().getUsername();
String username = actualUsername != null ? actualUsername + " " : "";
platform.getLogger().log(Level.INFO, "{0}{1} {2}: {3} (0x{4}) -> {5} (0x{6}) [{7}] {8}",
new Object[]{
username,
direction,
state,
originalID,
Integer.toHexString(originalID),
packetWrapper.getId(),
Integer.toHexString(packetWrapper.getId()),
Integer.toString(clientProtocol),
packetWrapper
});
}
/**
* Check if the pipeline contains a protocol
*
@@ -32,6 +32,7 @@ import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
import us.myles.ViaVersion.protocols.protocol1_16_1to1_16.Protocol1_16_1To1_16;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.Protocol1_16_2To1_16_1;
import us.myles.ViaVersion.protocols.protocol1_16_3to1_16_2.Protocol1_16_3To1_16_2;
import us.myles.ViaVersion.protocols.protocol1_16_4to1_16_3.Protocol1_16_4To1_16_3;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.Protocol1_16To1_15_2;
import us.myles.ViaVersion.protocols.protocol1_9_1_2to1_9_3_4.Protocol1_9_1_2To1_9_3_4;
import us.myles.ViaVersion.protocols.protocol1_9_1to1_9.Protocol1_9_1To1_9;
@@ -59,6 +60,7 @@ import java.util.concurrent.TimeUnit;
public class ProtocolRegistry {
public static final Protocol BASE_PROTOCOL = new BaseProtocol();
public static int SERVER_PROTOCOL = -1;
public static int maxProtocolPathSize = 50;
// Input Version -> Output Version & Protocol (Allows fast lookup)
private static final Int2ObjectMap<Int2ObjectMap<Protocol>> registryMap = new Int2ObjectOpenHashMap<>(32);
private static final Map<Class<? extends Protocol>, Protocol> protocols = new HashMap<>();
@@ -79,15 +81,15 @@ public class ProtocolRegistry {
// Base Protocol
registerBaseProtocol(BASE_PROTOCOL, Range.lessThan(Integer.MIN_VALUE));
registerBaseProtocol(new BaseProtocol1_7(), Range.lessThan(ProtocolVersion.v1_16.getId()));
registerBaseProtocol(new BaseProtocol1_16(), Range.atLeast(ProtocolVersion.v1_16.getId()));
registerBaseProtocol(new BaseProtocol1_7(), Range.lessThan(ProtocolVersion.v1_16.getVersion()));
registerBaseProtocol(new BaseProtocol1_16(), Range.atLeast(ProtocolVersion.v1_16.getVersion()));
registerProtocol(new Protocol1_9To1_8(), ProtocolVersion.v1_9, ProtocolVersion.v1_8);
registerProtocol(new Protocol1_9_1To1_9(), Arrays.asList(ProtocolVersion.v1_9_1.getId(), ProtocolVersion.v1_9_2.getId()), ProtocolVersion.v1_9.getId());
registerProtocol(new Protocol1_9_1To1_9(), Arrays.asList(ProtocolVersion.v1_9_1.getVersion(), ProtocolVersion.v1_9_2.getVersion()), ProtocolVersion.v1_9.getVersion());
registerProtocol(new Protocol1_9_3To1_9_1_2(), ProtocolVersion.v1_9_3, ProtocolVersion.v1_9_2);
registerProtocol(new Protocol1_9To1_9_1(), ProtocolVersion.v1_9, ProtocolVersion.v1_9_2);
registerProtocol(new Protocol1_9_1_2To1_9_3_4(), Arrays.asList(ProtocolVersion.v1_9_1.getId(), ProtocolVersion.v1_9_2.getId()), ProtocolVersion.v1_9_3.getId());
registerProtocol(new Protocol1_9_1_2To1_9_3_4(), Arrays.asList(ProtocolVersion.v1_9_1.getVersion(), ProtocolVersion.v1_9_2.getVersion()), ProtocolVersion.v1_9_3.getVersion());
registerProtocol(new Protocol1_10To1_9_3_4(), ProtocolVersion.v1_10, ProtocolVersion.v1_9_3);
registerProtocol(new Protocol1_11To1_10(), ProtocolVersion.v1_11, ProtocolVersion.v1_10);
@@ -115,6 +117,7 @@ public class ProtocolRegistry {
registerProtocol(new Protocol1_16_1To1_16(), ProtocolVersion.v1_16_1, ProtocolVersion.v1_16);
registerProtocol(new Protocol1_16_2To1_16_1(), ProtocolVersion.v1_16_2, ProtocolVersion.v1_16_1);
registerProtocol(new Protocol1_16_3To1_16_2(), ProtocolVersion.v1_16_3, ProtocolVersion.v1_16_2);
registerProtocol(new Protocol1_16_4To1_16_3(), ProtocolVersion.v1_16_4, ProtocolVersion.v1_16_3);
}
public static void init() {
@@ -129,7 +132,7 @@ public class ProtocolRegistry {
* @param output The output server version it converts to.
*/
public static void registerProtocol(Protocol protocol, ProtocolVersion supported, ProtocolVersion output) {
registerProtocol(protocol, Collections.singletonList(supported.getId()), output.getId());
registerProtocol(protocol, Collections.singletonList(supported.getVersion()), output.getVersion());
}
/**
@@ -193,9 +196,9 @@ public class ProtocolRegistry {
supportedVersions.add(ProtocolRegistry.SERVER_PROTOCOL);
for (ProtocolVersion versions : ProtocolVersion.getProtocols()) {
List<Pair<Integer, Protocol>> paths = getProtocolPath(versions.getId(), ProtocolRegistry.SERVER_PROTOCOL);
List<Pair<Integer, Protocol>> paths = getProtocolPath(versions.getVersion(), ProtocolRegistry.SERVER_PROTOCOL);
if (paths == null) continue;
supportedVersions.add(versions.getId());
supportedVersions.add(versions.getVersion());
for (Pair<Integer, Protocol> path : paths) {
supportedVersions.add(path.getKey());
}
@@ -244,7 +247,7 @@ public class ProtocolRegistry {
@Nullable
private static List<Pair<Integer, Protocol>> getProtocolPath(List<Pair<Integer, Protocol>> current, int clientVersion, int serverVersion) {
if (clientVersion == serverVersion) return null; // We're already there
if (current.size() > 50) return null; // Fail safe, protocol too complicated.
if (current.size() > maxProtocolPathSize) return null; // Fail safe, protocol too complicated.
// First check if there is any protocols for this
Int2ObjectMap<Protocol> inputMap = registryMap.get(clientVersion);
@@ -374,6 +377,7 @@ public class ProtocolRegistry {
}
private static void shutdownLoaderExecutor() {
Via.getPlatform().getLogger().info("Shutting down mapping loader executor!");
mappingsLoaded = true;
mappingLoaderExecutor.shutdown();
mappingLoaderExecutor = null;
@@ -1,111 +1,88 @@
package us.myles.ViaVersion.api.protocol;
import com.google.common.base.Preconditions;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ProtocolVersion {
private static final Map<Integer, ProtocolVersion> versions = new HashMap<>();
private static final Int2ObjectMap<ProtocolVersion> versions = new Int2ObjectOpenHashMap<>();
private static final List<ProtocolVersion> versionList = new ArrayList<>();
public static final ProtocolVersion v1_4_6;
public static final ProtocolVersion v1_5_1;
public static final ProtocolVersion v1_5_2;
public static final ProtocolVersion v_1_6_1;
public static final ProtocolVersion v_1_6_2;
public static final ProtocolVersion v_1_6_3;
public static final ProtocolVersion v_1_6_4;
public static final ProtocolVersion v1_7_1;
public static final ProtocolVersion v1_7_6;
public static final ProtocolVersion v1_8;
public static final ProtocolVersion v1_9;
public static final ProtocolVersion v1_9_1;
public static final ProtocolVersion v1_9_2;
public static final ProtocolVersion v1_9_3;
public static final ProtocolVersion v1_10;
public static final ProtocolVersion v1_11;
public static final ProtocolVersion v1_11_1;
public static final ProtocolVersion v1_12;
public static final ProtocolVersion v1_12_1;
public static final ProtocolVersion v1_12_2;
public static final ProtocolVersion v1_13;
public static final ProtocolVersion v1_13_1;
public static final ProtocolVersion v1_13_2;
public static final ProtocolVersion v1_14;
public static final ProtocolVersion v1_14_1;
public static final ProtocolVersion v1_14_2;
public static final ProtocolVersion v1_14_3;
public static final ProtocolVersion v1_14_4;
public static final ProtocolVersion v1_15;
public static final ProtocolVersion v1_15_1;
public static final ProtocolVersion v1_15_2;
public static final ProtocolVersion v1_16;
public static final ProtocolVersion v1_16_1;
public static final ProtocolVersion v1_16_2;
public static final ProtocolVersion v1_16_3;
public static final ProtocolVersion unknown;
// Before the Netty rewrite
public static final ProtocolVersion v1_4_6 = register(51, "1.4.6/7", new VersionRange("1.4", 6, 7));
public static final ProtocolVersion v1_5_1 = register(60, "1.5.1");
public static final ProtocolVersion v1_5_2 = register(61, "1.5.2");
public static final ProtocolVersion v_1_6_1 = register(73, "1.6.1");
public static final ProtocolVersion v_1_6_2 = register(74, "1.6.2");
public static final ProtocolVersion v_1_6_3 = register(77, "1.6.3");
public static final ProtocolVersion v_1_6_4 = register(78, "1.6.4");
// After the Netty rewrite
public static final ProtocolVersion v1_7_1 = register(4, "1.7-1.7.5", new VersionRange("1.7", 0, 5));
public static final ProtocolVersion v1_7_6 = register(5, "1.7.6-1.7.10", new VersionRange("1.7", 6, 10));
public static final ProtocolVersion v1_8 = register(47, "1.8.x");
public static final ProtocolVersion v1_9 = register(107, "1.9");
public static final ProtocolVersion v1_9_1 = register(108, "1.9.1");
public static final ProtocolVersion v1_9_2 = register(109, "1.9.2");
public static final ProtocolVersion v1_9_3 = register(110, "1.9.3/4", new VersionRange("1.9", 3, 4));
public static final ProtocolVersion v1_10 = register(210, "1.10.x");
public static final ProtocolVersion v1_11 = register(315, "1.11");
public static final ProtocolVersion v1_11_1 = register(316, "1.11.1/2", new VersionRange("1.11", 1, 2));
public static final ProtocolVersion v1_12 = register(335, "1.12");
public static final ProtocolVersion v1_12_1 = register(338, "1.12.1");
public static final ProtocolVersion v1_12_2 = register(340, "1.12.2");
public static final ProtocolVersion v1_13 = register(393, "1.13");
public static final ProtocolVersion v1_13_1 = register(401, "1.13.1");
public static final ProtocolVersion v1_13_2 = register(404, "1.13.2");
public static final ProtocolVersion v1_14 = register(477, "1.14");
public static final ProtocolVersion v1_14_1 = register(480, "1.14.1");
public static final ProtocolVersion v1_14_2 = register(485, "1.14.2");
public static final ProtocolVersion v1_14_3 = register(490, "1.14.3");
public static final ProtocolVersion v1_14_4 = register(498, "1.14.4");
public static final ProtocolVersion v1_15 = register(573, "1.15");
public static final ProtocolVersion v1_15_1 = register(575, "1.15.1");
public static final ProtocolVersion v1_15_2 = register(578, "1.15.2");
public static final ProtocolVersion v1_16 = register(735, "1.16");
public static final ProtocolVersion v1_16_1 = register(736, "1.16.1");
public static final ProtocolVersion v1_16_2 = register(751, "1.16.2");
public static final ProtocolVersion v1_16_3 = register(753, "1.16.3");
public static final ProtocolVersion v1_16_4 = register(754, "1.16.4");
public static final ProtocolVersion unknown = register(-1, "UNKNOWN");
private final int id;
private final String name;
static {
// Before netty rewrite
register(v1_4_6 = new ProtocolVersion(51, "1.4.6"));
register(v1_5_1 = new ProtocolVersion(60, "1.5.1"));
register(v1_5_2 = new ProtocolVersion(61, "1.5.2"));
register(v_1_6_1 = new ProtocolVersion(73, "1.6.1"));
register(v_1_6_2 = new ProtocolVersion(74, "1.6.2"));
register(v_1_6_3 = new ProtocolVersion(77, "1.6.3"));
register(v_1_6_4 = new ProtocolVersion(78, "1.6.4"));
// After netty rewrite
register(v1_7_1 = new ProtocolVersion(4, "1.7-1.7.5"));
register(v1_7_6 = new ProtocolVersion(5, "1.7.6-1.7.10"));
register(v1_8 = new ProtocolVersion(47, "1.8.x"));
register(v1_9 = new ProtocolVersion(107, "1.9"));
register(v1_9_1 = new ProtocolVersion(108, "1.9.1"));
register(v1_9_2 = new ProtocolVersion(109, "1.9.2"));
register(v1_9_3 = new ProtocolVersion(110, "1.9.3/4"));
register(v1_10 = new ProtocolVersion(210, "1.10"));
register(v1_11 = new ProtocolVersion(315, "1.11"));
register(v1_11_1 = new ProtocolVersion(316, "1.11.1"));
register(v1_12 = new ProtocolVersion(335, "1.12"));
register(v1_12_1 = new ProtocolVersion(338, "1.12.1"));
register(v1_12_2 = new ProtocolVersion(340, "1.12.2"));
register(v1_13 = new ProtocolVersion(393, "1.13"));
register(v1_13_1 = new ProtocolVersion(401, "1.13.1"));
register(v1_13_2 = new ProtocolVersion(404, "1.13.2"));
register(v1_14 = new ProtocolVersion(477, "1.14"));
register(v1_14_1 = new ProtocolVersion(480, "1.14.1"));
register(v1_14_2 = new ProtocolVersion(485, "1.14.2"));
register(v1_14_3 = new ProtocolVersion(490, "1.14.3"));
register(v1_14_4 = new ProtocolVersion(498, "1.14.4"));
register(v1_15 = new ProtocolVersion(573, "1.15"));
register(v1_15_1 = new ProtocolVersion(575, "1.15.1"));
register(v1_15_2 = new ProtocolVersion(578, "1.15.2"));
register(v1_16 = new ProtocolVersion(735, "1.16"));
register(v1_16_1 = new ProtocolVersion(736, "1.16.1"));
register(v1_16_2 = new ProtocolVersion(751, "1.16.2"));
register(v1_16_3 = new ProtocolVersion(753, "1.16.3"));
register(unknown = new ProtocolVersion(-1, "UNKNOWN"));
public static ProtocolVersion register(int version, String name) {
return register(version, -1, name);
}
public ProtocolVersion(int id, String name) {
this.id = id;
this.name = name;
public static ProtocolVersion register(int version, int snapshotVersion, String name) {
return register(version, snapshotVersion, name, null);
}
public static void register(ProtocolVersion protocol) {
Preconditions.checkNotNull(protocol);
versions.put(protocol.getId(), protocol);
public static ProtocolVersion register(int version, String name, @Nullable VersionRange versionRange) {
return register(version, -1, name, versionRange);
}
public static ProtocolVersion register(int version, int snapshotVersion, String name, @Nullable VersionRange versionRange) {
ProtocolVersion protocol = new ProtocolVersion(version, snapshotVersion, name, versionRange);
versionList.add(protocol);
versions.put(protocol.getVersion(), protocol);
if (protocol.isSnapshot()) {
versions.put(protocol.getFullSnapshotVersion(), protocol);
}
return protocol;
}
public static boolean isRegistered(int id) {
return versions.containsKey(id);
}
@NotNull
public static ProtocolVersion getProtocol(int id) {
ProtocolVersion protocolVersion = versions.get(id);
if (protocolVersion != null) {
@@ -123,48 +100,154 @@ public class ProtocolVersion {
return Collections.unmodifiableList(new ArrayList<>(versions.values()));
}
@Nullable
public static ProtocolVersion getClosest(String protocol) {
for (ProtocolVersion version : versions.values()) {
if (version.getName().equals(protocol))
String name = version.getName();
if (name.equals(protocol)) {
return version;
if (version.getName().equals(protocol + ".x"))
return version;
String[] parts = version.getName().split("-");
for (String part : parts) {
if (part.equalsIgnoreCase(protocol)) {
}
if (version.isVersionWildcard()) {
// Test against the major version with and without a minor version
String majorVersion = name.substring(0, name.length() - 2);
if (majorVersion.equals(protocol) || (protocol.startsWith(name.substring(0, name.length() - 1)))) {
return version;
}
if (part.equals(protocol + ".x"))
} else if (version.isRange()) {
if (version.getIncludedVersions().contains(protocol)) {
return version;
}
}
}
return null;
}
public int getId() {
return id;
private final int version;
private final int snapshotVersion;
private final String name;
private final boolean versionWildcard;
private final Set<String> includedVersions;
public ProtocolVersion(int version, String name) {
this(version, -1, name, null);
}
public ProtocolVersion(int version, int snapshotVersion, String name, @Nullable VersionRange versionRange) {
this.version = version;
this.snapshotVersion = snapshotVersion;
this.name = name;
this.versionWildcard = name.endsWith(".x");
Preconditions.checkArgument(!versionWildcard || versionRange == null, "A version cannot be a wildcard and a range at the same time!");
if (versionRange != null) {
includedVersions = new HashSet<>();
for (int i = versionRange.getRangeFrom(); i <= versionRange.getRangeTo(); i++) {
if (i == 0) {
includedVersions.add(versionRange.getBaseVersion()); // Keep both the base version and with ".0" appended
}
includedVersions.add(versionRange.getBaseVersion() + "." + i);
}
} else {
includedVersions = Collections.singleton(name);
}
}
/**
* @return release version
*/
public int getVersion() {
return version;
}
/**
* @return snapshot protocol version without the snapshot indicator bit
* @throws IllegalArgumentException if the version if not a snapshot version
* @see #isSnapshot()
*/
public int getSnapshotVersion() {
Preconditions.checkArgument(isSnapshot());
return snapshotVersion;
}
/**
* @return snapshot protocol version with the snapshot indicator bit
* @throws IllegalArgumentException if the version if not a snapshot version
* @see #isSnapshot()
*/
public int getFullSnapshotVersion() {
Preconditions.checkArgument(isSnapshot());
return (1 << 30) | snapshotVersion; // Bit indicating snapshot versions
}
/**
* @return release version if release, snapshot version (with the snapshot indicator bit) if snapshot
*/
public int getOriginalVersion() {
return snapshotVersion == -1 ? version : ((1 << 30) | snapshotVersion);
}
/**
* @return true if the protocol includes a range of versions (but not an entire major version range), for example 1.7-1.7.5
* @see #getIncludedVersions()
*/
public boolean isRange() {
return includedVersions.size() != 1;
}
/**
* Returns an immutable set of all included versions if the protocol is a version range.
* If the protocol only includes a single Minecraft version or the entire major version as a wildcard ({@link #isVersionWildcard()}),
* the set will only contain the string given in {@link #getName()}.
*
* @return immutable set of all included versions if the protocol is a version range
* @see #isRange()
*/
public Set<String> getIncludedVersions() {
return Collections.unmodifiableSet(includedVersions);
}
/**
* @return true if the protocol includes an entire major version range (for example 1.8.x)
*/
public boolean isVersionWildcard() {
return versionWildcard;
}
public String getName() {
return name;
}
public boolean isSnapshot() {
return snapshotVersion != -1;
}
/**
* @return release version
* @deprecated ambiguous, see {@link #getOriginalVersion()}, {@link #getVersion()}, and {@link #getSnapshotVersion()}
*/
@Deprecated
public int getId() {
return version;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ProtocolVersion that = (ProtocolVersion) o;
return id == that.id;
return version == that.version;
}
@Override
public int hashCode() {
return id;
return version;
}
@Override
public String toString() {
return String.format("%s(%d)", this.getName(), this.getId());
return String.format("%s(%d)", this.name, this.version);
}
}
@@ -11,10 +11,6 @@ public abstract class SimpleProtocol extends Protocol<SimpleProtocol.DummyPacket
protected SimpleProtocol() {
}
protected SimpleProtocol(boolean hasMappingDataToLoad) {
super(hasMappingDataToLoad);
}
public enum DummyPacketTypes implements ClientboundPacketType, ServerboundPacketType {
}
}
@@ -0,0 +1,37 @@
package us.myles.ViaVersion.api.protocol;
import com.google.common.base.Preconditions;
public class VersionRange {
private final String baseVersion;
private final int rangeFrom;
private final int rangeTo;
/**
* Creates a new version range. Giving "1.7", 0, and 5 for example would represent the range from 1.7-1.7.5.
*
* @param baseVersion base version
* @param rangeFrom minor version the range begins at, must be greater than or equal to 0
* @param rangeTo minor version the range ends at, must be greater than {@code rangeFrom}
*/
public VersionRange(String baseVersion, int rangeFrom, int rangeTo) {
Preconditions.checkNotNull(baseVersion);
Preconditions.checkArgument(rangeFrom >= 0);
Preconditions.checkArgument(rangeTo > rangeFrom);
this.baseVersion = baseVersion;
this.rangeFrom = rangeFrom;
this.rangeTo = rangeTo;
}
public String getBaseVersion() {
return baseVersion;
}
public int getRangeFrom() {
return rangeFrom;
}
public int getRangeTo() {
return rangeTo;
}
}
@@ -1,9 +1,7 @@
package us.myles.ViaVersion.api.rewriters;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.minecraft.BlockChangeRecord;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.ClientboundPacketType;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
@@ -12,15 +10,11 @@ import us.myles.ViaVersion.api.type.Type;
// If any of these methods become outdated, just create a new rewriter overriding the methods
public class BlockRewriter {
private final Protocol protocol;
private final IdRewriteFunction blockStateRewriter;
private final IdRewriteFunction blockRewriter;
private final Type<Position> positionType;
public BlockRewriter(Protocol protocol, Type<Position> positionType, IdRewriteFunction blockStateRewriter, IdRewriteFunction blockRewriter) {
public BlockRewriter(Protocol protocol, Type<Position> positionType) {
this.protocol = protocol;
this.positionType = positionType;
this.blockStateRewriter = blockStateRewriter;
this.blockRewriter = blockRewriter;
}
public void registerBlockAction(ClientboundPacketType packetType) {
@@ -33,7 +27,7 @@ public class BlockRewriter {
map(Type.VAR_INT); // Block id - /!\ NOT BLOCK STATE
handler(wrapper -> {
int id = wrapper.get(Type.VAR_INT, 0);
int mappedId = blockRewriter.rewrite(id);
int mappedId = protocol.getMappingData().getNewBlockId(id);
if (mappedId == -1) {
// Block (action) has been removed
wrapper.cancel();
@@ -52,7 +46,7 @@ public class BlockRewriter {
public void registerMap() {
map(positionType);
map(Type.VAR_INT);
handler(wrapper -> wrapper.set(Type.VAR_INT, 0, blockStateRewriter.rewrite(wrapper.get(Type.VAR_INT, 0))));
handler(wrapper -> wrapper.set(Type.VAR_INT, 0, protocol.getMappingData().getNewBlockStateId(wrapper.get(Type.VAR_INT, 0))));
}
});
}
@@ -65,7 +59,7 @@ public class BlockRewriter {
map(Type.INT); // 1 - Chunk Z
handler(wrapper -> {
for (BlockChangeRecord record : wrapper.passthrough(Type.BLOCK_CHANGE_RECORD_ARRAY)) {
record.setBlockId(blockStateRewriter.rewrite(record.getBlockId()));
record.setBlockId(protocol.getMappingData().getNewBlockStateId(record.getBlockId()));
}
});
}
@@ -79,7 +73,7 @@ public class BlockRewriter {
map(Type.LONG); // Chunk position
handler(wrapper -> {
for (BlockChangeRecord record : wrapper.passthrough(Type.VAR_LONG_BLOCK_CHANGE_RECORD_ARRAY)) {
record.setBlockId(blockStateRewriter.rewrite(record.getBlockId()));
record.setBlockId(protocol.getMappingData().getNewBlockStateId(record.getBlockId()));
}
});
}
@@ -91,7 +85,7 @@ public class BlockRewriter {
registerBlockChange(packetType);
}
public void registerEffect(ClientboundPacketType packetType, int playRecordId, int blockBreakId, IdRewriteFunction itemIdRewriteFunction) {
public void registerEffect(ClientboundPacketType packetType, int playRecordId, int blockBreakId) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
@@ -102,51 +96,9 @@ public class BlockRewriter {
int id = wrapper.get(Type.INT, 0);
int data = wrapper.get(Type.INT, 1);
if (id == playRecordId) { // Play record
wrapper.set(Type.INT, 1, itemIdRewriteFunction.rewrite(data));
wrapper.set(Type.INT, 1, protocol.getMappingData().getNewItemId(data));
} else if (id == blockBreakId) { // Block break + block break sound
wrapper.set(Type.INT, 1, blockStateRewriter.rewrite(data));
}
});
}
});
}
public void registerSpawnParticle(ClientboundPacketType packetType, int blockId, int fallingDustId, int itemId,
ItemRewriter.RewriteFunction itemRewriteFunction, Type<Item> itemType, Type<?> coordType) {
registerSpawnParticle(packetType, blockId, fallingDustId, itemId, null, itemRewriteFunction, itemType, coordType);
}
public void registerSpawnParticle(ClientboundPacketType packetType, int blockId, int fallingDustId, int itemId,
@Nullable IdRewriteFunction particleRewriteFunction, ItemRewriter.RewriteFunction itemRewriteFunction, Type<Item> itemType, Type<?> coordType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Particle ID
map(Type.BOOLEAN); // 1 - Long Distance
map(coordType); // 2 - X
map(coordType); // 3 - Y
map(coordType); // 4 - Z
map(Type.FLOAT); // 5 - Offset X
map(Type.FLOAT); // 6 - Offset Y
map(Type.FLOAT); // 7 - Offset Z
map(Type.FLOAT); // 8 - Particle Data
map(Type.INT); // 9 - Particle Count
handler(wrapper -> {
int id = wrapper.get(Type.INT, 0);
if (id == -1) return;
if (id == blockId || id == fallingDustId) {
int data = wrapper.passthrough(Type.VAR_INT);
wrapper.set(Type.VAR_INT, 0, blockStateRewriter.rewrite(data));
} else if (id == itemId) {
// Has to be like this, until we make *everything* object oriented inside of each protocol :(
itemRewriteFunction.rewrite(wrapper.passthrough(itemType));
}
if (particleRewriteFunction != null) {
int newId = particleRewriteFunction.rewrite(id);
if (newId != id) {
wrapper.set(Type.INT, 0, newId);
}
wrapper.set(Type.INT, 1, protocol.getMappingData().getNewBlockStateId(data));
}
});
}
@@ -180,4 +180,8 @@ public class ComponentRewriter {
processText(jsonElement);
}
}
public <T extends Protocol> T getProtocol() {
return (T) protocol;
}
}
@@ -1,5 +1,6 @@
package us.myles.ViaVersion.api.rewriters;
import us.myles.ViaVersion.api.data.ParticleMappings;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.ClientboundPacketType;
import us.myles.ViaVersion.api.protocol.Protocol;
@@ -106,13 +107,13 @@ public class ItemRewriter {
});
}
public void registerSetCooldown(ClientboundPacketType packetType, IdRewriteFunction itemIDRewriteFunction) {
public void registerSetCooldown(ClientboundPacketType packetType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
handler(wrapper -> {
int itemId = wrapper.read(Type.VAR_INT);
wrapper.write(Type.VAR_INT, itemIDRewriteFunction.rewrite(itemId));
wrapper.write(Type.VAR_INT, protocol.getMappingData().getNewItemId(itemId));
});
}
});
@@ -189,6 +190,42 @@ public class ItemRewriter {
});
}
// Not the very best place for this, but has to stay here until *everything* is abstracted
public void registerSpawnParticle(ClientboundPacketType packetType, Type<Item> itemType, Type<?> coordType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.INT); // 0 - Particle ID
map(Type.BOOLEAN); // 1 - Long Distance
map(coordType); // 2 - X
map(coordType); // 3 - Y
map(coordType); // 4 - Z
map(Type.FLOAT); // 5 - Offset X
map(Type.FLOAT); // 6 - Offset Y
map(Type.FLOAT); // 7 - Offset Z
map(Type.FLOAT); // 8 - Particle Data
map(Type.INT); // 9 - Particle Count
handler(wrapper -> {
int id = wrapper.get(Type.INT, 0);
if (id == -1) return;
ParticleMappings mappings = protocol.getMappingData().getParticleMappings();
if (id == mappings.getBlockId() || id == mappings.getFallingDustId()) {
int data = wrapper.passthrough(Type.VAR_INT);
wrapper.set(Type.VAR_INT, 0, protocol.getMappingData().getNewBlockStateId(data));
} else if (id == mappings.getItemId()) {
toClient.rewrite(wrapper.passthrough(itemType));
}
int newId = protocol.getMappingData().getNewParticleId(id);
if (newId != id) {
wrapper.set(Type.INT, 0, newId);
}
});
}
});
}
// Only sent to the client
public PacketHandler itemArrayHandler(Type<Item[]> type) {
return wrapper -> {
@@ -4,6 +4,7 @@ import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.ParticleMappings;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.entities.EntityType;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
@@ -13,6 +14,7 @@ import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.storage.EntityTracker;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.Particle;
import java.util.ArrayList;
import java.util.List;
@@ -20,7 +22,7 @@ import java.util.logging.Logger;
public abstract class MetadataRewriter {
private final Class<? extends EntityTracker> entityTrackerClass;
private final Protocol protocol;
protected final Protocol protocol;
private Int2IntMap typeMapping;
protected MetadataRewriter(Protocol protocol, Class<? extends EntityTracker> entityTrackerClass) {
@@ -50,6 +52,20 @@ public abstract class MetadataRewriter {
}
}
protected void rewriteParticle(Particle particle) {
ParticleMappings mappings = protocol.getMappingData().getParticleMappings();
int id = particle.getId();
if (id == mappings.getBlockId() || id == mappings.getFallingDustId()) {
Particle.ParticleData data = particle.getArguments().get(0);
data.setValue(protocol.getMappingData().getNewBlockStateId(data.get()));
} else if (id == mappings.getItemId()) {
Particle.ParticleData data = particle.getArguments().get(0);
data.setValue(protocol.getMappingData().getNewItemId(data.get()));
}
particle.setId(protocol.getMappingData().getNewParticleId(id));
}
//TODO add respawn/join once they stop changing too much
public void registerTracker(ClientboundPacketType packetType) {
@@ -64,7 +80,7 @@ public abstract class MetadataRewriter {
});
}
public void registerSpawnTrackerWithData(ClientboundPacketType packetType, EntityType fallingBlockType, IdRewriteFunction itemRewriter) {
public void registerSpawnTrackerWithData(ClientboundPacketType packetType, EntityType fallingBlockType) {
protocol.registerOutgoing(packetType, new PacketRemapper() {
@Override
public void registerMap() {
@@ -82,7 +98,7 @@ public abstract class MetadataRewriter {
int entityId = wrapper.get(Type.VAR_INT, 0);
EntityType entityType = wrapper.user().get(entityTrackerClass).getEntity(entityId);
if (entityType == fallingBlockType) {
wrapper.set(Type.INT, 0, itemRewriter.rewrite(wrapper.get(Type.INT, 0)));
wrapper.set(Type.INT, 0, protocol.getMappingData().getNewBlockStateId(wrapper.get(Type.INT, 0)));
}
});
}
@@ -7,9 +7,13 @@ import us.myles.ViaVersion.api.type.Type;
public class SoundRewriter {
protected final Protocol protocol;
// Can't hold the mappings instance here since it's loaded later
protected final IdRewriteFunction idRewriter;
public SoundRewriter(Protocol protocol) {
this.protocol = protocol;
this.idRewriter = id -> protocol.getMappingData().getSoundMappings().getNewId(id);
}
public SoundRewriter(Protocol protocol, IdRewriteFunction idRewriter) {
this.protocol = protocol;
this.idRewriter = idRewriter;
@@ -8,24 +8,12 @@ import us.myles.ViaVersion.api.type.Type;
public class StatisticsRewriter {
private final Protocol protocol;
private final IdRewriteFunction blockRewriter;
private final IdRewriteFunction itemRewriter;
private final IdRewriteFunction entityRewriter;
private final IdRewriteFunction statisticsIdRewriter;
private final int customStatsCategory = 8; // Make this changeable if it differs in a future version
public StatisticsRewriter(Protocol protocol,
@Nullable IdRewriteFunction blockRewriter, @Nullable IdRewriteFunction itemRewriter, @Nullable IdRewriteFunction entityRewriter,
@Nullable IdRewriteFunction statisticsIdRewriter) {
public StatisticsRewriter(Protocol protocol, @Nullable IdRewriteFunction entityRewriter) {
this.protocol = protocol;
this.blockRewriter = blockRewriter;
this.itemRewriter = itemRewriter;
this.entityRewriter = entityRewriter;
this.statisticsIdRewriter = statisticsIdRewriter;
}
public StatisticsRewriter(Protocol protocol, @Nullable IdRewriteFunction blockRewriter, @Nullable IdRewriteFunction itemRewriter, @Nullable IdRewriteFunction entityRewriter) {
this(protocol, blockRewriter, itemRewriter, entityRewriter, null);
}
public void register(ClientboundPacketType packetType) {
@@ -39,9 +27,9 @@ public class StatisticsRewriter {
int categoryId = wrapper.read(Type.VAR_INT);
int statisticId = wrapper.read(Type.VAR_INT);
int value = wrapper.read(Type.VAR_INT);
if (categoryId == customStatsCategory && statisticsIdRewriter != null) {
if (categoryId == customStatsCategory && protocol.getMappingData().getStatisticsMappings() != null) {
// Rewrite custom statistics id
statisticId = statisticsIdRewriter.rewrite(statisticId);
statisticId = protocol.getMappingData().getStatisticsMappings().getNewId(statisticId);
if (statisticId == -1) {
// Remove entry
newSize--;
@@ -73,9 +61,9 @@ public class StatisticsRewriter {
protected IdRewriteFunction getRewriter(RegistryType type) {
switch (type) {
case BLOCK:
return blockRewriter;
return protocol.getMappingData().getBlockMappings() != null ? id -> protocol.getMappingData().getNewBlockId(id) : null;
case ITEM:
return itemRewriter;
return protocol.getMappingData().getItemMappings() != null ? id -> protocol.getMappingData().getNewItemId(id) : null;
case ENTITY:
return entityRewriter;
}
@@ -2,7 +2,9 @@ package us.myles.ViaVersion.api.rewriters;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.data.MappingData;
import us.myles.ViaVersion.api.protocol.ClientboundPacketType;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
@@ -14,18 +16,14 @@ import java.util.List;
public class TagRewriter {
private static final int[] EMPTY_ARRAY = {};
private final Protocol protocol;
private final IdRewriteFunction blockRewriter;
private final IdRewriteFunction itemRewriter;
private final IdRewriteFunction entityRewriter;
private final List<TagData> newBlockTags = new ArrayList<>();
private final List<TagData> newItemTags = new ArrayList<>();
private final List<TagData> newEntityTags = new ArrayList<>();
// add fluid tag list if needed at some point
public TagRewriter(Protocol protocol, IdRewriteFunction blockRewriter, IdRewriteFunction itemRewriter, IdRewriteFunction entityRewriter) {
public TagRewriter(Protocol protocol, @Nullable IdRewriteFunction entityRewriter) {
this.protocol = protocol;
this.blockRewriter = blockRewriter;
this.itemRewriter = itemRewriter;
this.entityRewriter = entityRewriter;
}
@@ -58,8 +56,9 @@ public class TagRewriter {
@Override
public void registerMap() {
handler(wrapper -> {
handle(wrapper, blockRewriter, newBlockTags);
handle(wrapper, itemRewriter, newItemTags);
MappingData mappingData = protocol.getMappingData();
handle(wrapper, id -> mappingData != null ? mappingData.getNewBlockId(id) : null, newBlockTags);
handle(wrapper, id -> mappingData != null ? mappingData.getNewItemId(id) : null, newItemTags);
if (entityRewriter == null && newEntityTags.isEmpty()) return;
@@ -122,12 +121,13 @@ public class TagRewriter {
}
}
@Nullable
private IdRewriteFunction getRewriter(RegistryType tagType) {
switch (tagType) {
case BLOCK:
return blockRewriter;
return protocol.getMappingData().getBlockMappings() != null ? id -> protocol.getMappingData().getNewBlockId(id) : null;
case ITEM:
return itemRewriter;
return protocol.getMappingData().getItemMappings() != null ? id -> protocol.getMappingData().getNewItemId(id) : null;
case ENTITY:
return entityRewriter;
case FLUID:
@@ -50,6 +50,10 @@ public class Particle {
return value;
}
public <T> T get() {
return (T) value;
}
public void setValue(Object value) {
this.value = value;
}
@@ -14,8 +14,6 @@ public class ChunkSectionType1_13 extends Type<ChunkSection> {
@Override
public ChunkSection read(ByteBuf buffer) throws Exception {
ChunkSection chunkSection = new ChunkSection();
// Reaad bits per block
int bitsPerBlock = buffer.readUnsignedByte();
int originalBitsPerBlock = bitsPerBlock;
@@ -24,11 +22,16 @@ public class ChunkSectionType1_13 extends Type<ChunkSection> {
bitsPerBlock = GLOBAL_PALETTE;
}
int paletteLength = bitsPerBlock == GLOBAL_PALETTE ? 0 : Type.VAR_INT.readPrimitive(buffer);
// Read palette
chunkSection.clearPalette();
for (int i = 0; i < paletteLength; i++) {
chunkSection.addPaletteEntry(Type.VAR_INT.readPrimitive(buffer));
ChunkSection chunkSection;
if (bitsPerBlock != GLOBAL_PALETTE) {
int paletteLength = Type.VAR_INT.readPrimitive(buffer);
chunkSection = new ChunkSection(paletteLength);
for (int i = 0; i < paletteLength; i++) {
chunkSection.addPaletteEntry(Type.VAR_INT.readPrimitive(buffer));
}
} else {
chunkSection = new ChunkSection();
}
// Read blocks
@@ -14,8 +14,6 @@ public class ChunkSectionType1_16 extends Type<ChunkSection> {
@Override
public ChunkSection read(ByteBuf buffer) throws Exception {
ChunkSection chunkSection = new ChunkSection();
// Reaad bits per block
int bitsPerBlock = buffer.readUnsignedByte();
int originalBitsPerBlock = bitsPerBlock;
@@ -24,11 +22,16 @@ public class ChunkSectionType1_16 extends Type<ChunkSection> {
bitsPerBlock = GLOBAL_PALETTE;
}
int paletteLength = bitsPerBlock == GLOBAL_PALETTE ? 0 : Type.VAR_INT.readPrimitive(buffer);
// Read palette
chunkSection.clearPalette();
for (int i = 0; i < paletteLength; i++) {
chunkSection.addPaletteEntry(Type.VAR_INT.readPrimitive(buffer));
ChunkSection chunkSection;
if (bitsPerBlock != GLOBAL_PALETTE) {
int paletteLength = Type.VAR_INT.readPrimitive(buffer);
chunkSection = new ChunkSection(paletteLength);
for (int i = 0; i < paletteLength; i++) {
chunkSection.addPaletteEntry(Type.VAR_INT.readPrimitive(buffer));
}
} else {
chunkSection = new ChunkSection();
}
// Read blocks
@@ -15,7 +15,8 @@ public class ChunkSectionType1_8 extends Type<ChunkSection> {
@Override
public ChunkSection read(ByteBuf buffer) throws Exception {
ChunkSection chunkSection = new ChunkSection();
// Don't clear palette because 0 index needs to be air in 1.9 version
// 0 index needs to be air in 1.9
chunkSection.addPaletteEntry(0);
ByteBuf littleEndianView = buffer.order(ByteOrder.LITTLE_ENDIAN);
@@ -14,8 +14,6 @@ public class ChunkSectionType1_9 extends Type<ChunkSection> {
@Override
public ChunkSection read(ByteBuf buffer) throws Exception {
ChunkSection chunkSection = new ChunkSection();
// Reaad bits per block
int bitsPerBlock = buffer.readUnsignedByte();
int originalBitsPerBlock = bitsPerBlock;
@@ -29,9 +27,10 @@ public class ChunkSectionType1_9 extends Type<ChunkSection> {
if (bitsPerBlock > 8) {
bitsPerBlock = GLOBAL_PALETTE;
}
int paletteLength = Type.VAR_INT.readPrimitive(buffer);
// Read palette
chunkSection.clearPalette();
int paletteLength = Type.VAR_INT.readPrimitive(buffer);
ChunkSection chunkSection = bitsPerBlock != GLOBAL_PALETTE ? new ChunkSection(paletteLength) : new ChunkSection();
for (int i = 0; i < paletteLength; i++) {
if (bitsPerBlock != GLOBAL_PALETTE) {
chunkSection.addPaletteEntry(Type.VAR_INT.readPrimitive(buffer));
@@ -6,6 +6,7 @@ import us.myles.ViaVersion.api.command.ViaSubCommand;
import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
public class DontBugMeSubCmd extends ViaSubCommand {
@Override
public String name() {
return "dontbugme";
@@ -21,7 +22,7 @@ public class DontBugMeSubCmd extends ViaSubCommand {
ConfigurationProvider provider = Via.getPlatform().getConfigurationProvider();
boolean newValue = !Via.getConfig().isCheckForUpdates();
provider.set("checkforupdates", newValue);
Via.getConfig().setCheckForUpdates(newValue);
provider.saveConfig();
sendMessage(sender, "&6We will %snotify you about updates.", (newValue ? "&a" : "&cnot "));
@@ -8,6 +8,7 @@ import us.myles.ViaVersion.api.platform.providers.ViaProviders;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import us.myles.ViaVersion.api.protocol.SimpleProtocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
@@ -27,26 +28,27 @@ public class BaseProtocol extends SimpleProtocol {
@Override
public void registerMap() {
handler(wrapper -> {
int protVer = wrapper.passthrough(Type.VAR_INT);
int protocolVersion = wrapper.passthrough(Type.VAR_INT);
wrapper.passthrough(Type.STRING); // Server Address
wrapper.passthrough(Type.UNSIGNED_SHORT); // Server Port
int state = wrapper.passthrough(Type.VAR_INT);
ProtocolInfo info = wrapper.user().getProtocolInfo();
info.setProtocolVersion(protVer);
info.setProtocolVersion(protocolVersion);
// Ensure the server has a version provider
if (Via.getManager().getProviders().get(VersionProvider.class) == null) {
wrapper.user().setActive(false);
return;
}
// Choose the pipe
int protocol = Via.getManager().getProviders().get(VersionProvider.class).getServerProtocol(wrapper.user());
info.setServerProtocolVersion(protocol);
int serverProtocol = Via.getManager().getProviders().get(VersionProvider.class).getServerProtocol(wrapper.user());
info.setServerProtocolVersion(serverProtocol);
List<Pair<Integer, Protocol>> protocols = null;
// Only allow newer clients or (1.9.2 on 1.9.4 server if the server supports it)
if (info.getProtocolVersion() >= protocol || Via.getPlatform().isOldClientsAllowed()) {
protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocol);
if (info.getProtocolVersion() >= serverProtocol || Via.getPlatform().isOldClientsAllowed()) {
protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), serverProtocol);
}
ProtocolPipeline pipeline = wrapper.user().getProtocolInfo().getPipeline();
@@ -56,11 +58,14 @@ public class BaseProtocol extends SimpleProtocol {
// Ensure mapping data has already been loaded
ProtocolRegistry.completeMappingDataLoading(prot.getValue().getClass());
}
wrapper.set(Type.VAR_INT, 0, protocol);
// Set the original snapshot version if present
ProtocolVersion protocol = ProtocolVersion.getProtocol(serverProtocol);
wrapper.set(Type.VAR_INT, 0, protocol.getOriginalVersion());
}
// Add Base Protocol
pipeline.add(ProtocolRegistry.getBaseProtocol(protocol));
pipeline.add(ProtocolRegistry.getBaseProtocol(serverProtocol));
// Change state
if (state == 1) {
@@ -11,6 +11,7 @@ import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import us.myles.ViaVersion.api.protocol.SimpleProtocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
@@ -51,26 +52,30 @@ public class BaseProtocol1_7 extends SimpleProtocol {
protocolVersion = ((Long) version.get("protocol").getAsLong()).intValue();
}
} else {
version = new JsonObject();
json.getAsJsonObject().add("version", version);
json.getAsJsonObject().add("version", version = new JsonObject());
}
} else {
// Format properly
json = new JsonObject();
version = new JsonObject();
json.getAsJsonObject().add("version", version);
json.getAsJsonObject().add("version", version = new JsonObject());
}
if (Via.getConfig().isSendSupportedVersions()) { // Send supported versions
version.add("supportedVersions", GsonUtil.getGson().toJsonTree(Via.getAPI().getSupportedVersions()));
}
if (ProtocolRegistry.SERVER_PROTOCOL == -1) { // Set the Server protocol if the detection on startup failed
ProtocolRegistry.SERVER_PROTOCOL = ProtocolVersion.getProtocol(protocolVersion).getVersion();
}
if (Via.getConfig().isSendSupportedVersions()) //Send supported versions
version.add("supportedVersions", GsonUtil.getGson().toJsonTree(Via.getAPI().getSupportedVersions()));
if (ProtocolRegistry.SERVER_PROTOCOL == -1) // Set the Server protocol if the detection on startup failed
ProtocolRegistry.SERVER_PROTOCOL = protocolVersion;
// Ensure the server has a version provider
if (Via.getManager().getProviders().get(VersionProvider.class) == null) {
VersionProvider versionProvider = Via.getManager().getProviders().get(VersionProvider.class);
if (versionProvider == null) {
wrapper.user().setActive(false);
return;
}
int protocol = Via.getManager().getProviders().get(VersionProvider.class).getServerProtocol(wrapper.user());
int protocol = versionProvider.getServerProtocol(wrapper.user());
List<Pair<Integer, Protocol>> protocols = null;
// Only allow newer clients or (1.9.2 on 1.9.4 server if the server supports it)
@@ -79,17 +84,18 @@ public class BaseProtocol1_7 extends SimpleProtocol {
}
if (protocols != null) {
if (protocolVersion == protocol || protocolVersion == 0) {
//Fix ServerListPlus
version.addProperty("protocol", info.getProtocolVersion());
if (protocolVersion == protocol || protocolVersion == 0) { // Fix ServerListPlus
ProtocolVersion prot = ProtocolVersion.getProtocol(info.getProtocolVersion());
version.addProperty("protocol", prot.getOriginalVersion());
}
} else {
// not compatible :(, *plays very sad violin*
wrapper.user().setActive(false);
}
if (Via.getConfig().getBlockedProtocols().contains(info.getProtocolVersion()))
if (Via.getConfig().getBlockedProtocols().contains(info.getProtocolVersion())) {
version.addProperty("protocol", -1); // Show blocked versions as outdated
}
wrapper.set(Type.STRING, 0, GsonUtil.getGson().toJson(json)); // Update value
} catch (JsonParseException e) {
@@ -159,6 +165,7 @@ public class BaseProtocol1_7 extends SimpleProtocol {
int protocol = wrapper.user().getProtocolInfo().getProtocolVersion();
if (Via.getConfig().getBlockedProtocols().contains(protocol)) {
if (!wrapper.user().getChannel().isOpen()) return;
if (!wrapper.user().shouldApplyBlockProtocol()) return;
PacketWrapper disconnectPacket = new PacketWrapper(0x00, null, wrapper.user()); // Disconnect Packet
Protocol1_9To1_8.FIX_JSON.write(disconnectPacket, ChatColor.translateAlternateColorCodes('&', Via.getConfig().getBlockedDisconnectMsg()));
@@ -3,6 +3,7 @@ package us.myles.ViaVersion.protocols.base;
import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import us.myles.ViaVersion.packets.State;
import java.util.UUID;
@@ -32,7 +33,9 @@ public class ProtocolInfo extends StoredObject {
}
public void setProtocolVersion(int protocolVersion) {
this.protocolVersion = protocolVersion;
// Map snapshot versions to the higher/orderer release version
ProtocolVersion protocol = ProtocolVersion.getProtocol(protocolVersion);
this.protocolVersion = protocol.getVersion();
}
public int getServerProtocolVersion() {
@@ -40,7 +43,8 @@ public class ProtocolInfo extends StoredObject {
}
public void setServerProtocolVersion(int serverProtocolVersion) {
this.serverProtocolVersion = serverProtocolVersion;
ProtocolVersion protocol = ProtocolVersion.getProtocol(serverProtocolVersion);
this.serverProtocolVersion = protocol.getVersion();
}
public String getUsername() {
@@ -22,7 +22,7 @@ public class Protocol1_10To1_9_3_4 extends Protocol<ClientboundPackets1_9_3, Cli
public static final ValueTransformer<Short, Float> TO_NEW_PITCH = new ValueTransformer<Short, Float>(Type.FLOAT) {
@Override
public Float transform(PacketWrapper wrapper, Short inputValue) throws Exception {
return inputValue / 63.5F;
return inputValue / 63.0F;
}
};
public static final ValueTransformer<List<Metadata>, List<Metadata>> TRANSFORM_METADATA = new ValueTransformer<List<Metadata>, List<Metadata>>(Types1_9.METADATA_LIST) {
@@ -13,6 +13,7 @@ import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.remapper.ValueCreator;
import us.myles.ViaVersion.api.remapper.ValueTransformer;
import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.api.rewriters.SoundRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.version.Types1_9;
@@ -39,7 +40,7 @@ public class Protocol1_11To1_10 extends Protocol<ClientboundPackets1_9_3, Client
@Override
protected void registerPackets() {
MetadataRewriter1_11To1_10 metadataRewriter = new MetadataRewriter1_11To1_10(this);
MetadataRewriter metadataRewriter = new MetadataRewriter1_11To1_10(this);
InventoryPackets.register(this);
@@ -336,7 +337,7 @@ public class Protocol1_11To1_10 extends Protocol<ClientboundPackets1_9_3, Client
id += 1;
if (id >= 197) // evocation things
id += 8;
if (id >= 196) // Rip the Experience orb touch sound :'(
if (id >= 207) // Rip the Experience orb touch sound :'(
id -= 1;
if (id >= 279) // Liama's
id += 9;
@@ -13,6 +13,7 @@ import us.myles.ViaVersion.api.platform.providers.ViaProviders;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.api.rewriters.SoundRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.version.Types1_12;
@@ -34,7 +35,7 @@ public class Protocol1_12To1_11_1 extends Protocol<ClientboundPackets1_9_3, Clie
@Override
protected void registerPackets() {
MetadataRewriter1_12To1_11_1 metadataRewriter = new MetadataRewriter1_12To1_11_1(this);
MetadataRewriter metadataRewriter = new MetadataRewriter1_12To1_11_1(this);
InventoryPackets.register(this);
@@ -27,8 +27,15 @@ public class TranslateRewriter {
return;
}
String value = hoverEvent.getAsJsonPrimitive("value").getAsString();
if (AchievementTranslationMapping.get(value) == null) {
String textValue;
JsonElement value = hoverEvent.get("value");
if (value.isJsonObject()) {
textValue = value.getAsJsonObject().get("text").getAsString();
} else {
textValue = value.getAsJsonPrimitive().getAsString();
}
if (AchievementTranslationMapping.get(textValue) == null) {
JsonObject invalidText = new JsonObject();
invalidText.addProperty("text", "Invalid statistic/achievement!");
invalidText.addProperty("color", "red");
@@ -48,17 +55,17 @@ public class TranslateRewriter {
baseArray.add(namePart);
baseArray.add(newLine);
baseArray.add(typePart);
if (value.startsWith("achievement")) {
namePart.addProperty("translate", value);
namePart.addProperty("color", AchievementTranslationMapping.isSpecial(value) ? "dark_purple" : "green");
if (textValue.startsWith("achievement")) {
namePart.addProperty("translate", textValue);
namePart.addProperty("color", AchievementTranslationMapping.isSpecial(textValue) ? "dark_purple" : "green");
typePart.addProperty("translate", "stats.tooltip.type.achievement");
JsonObject description = new JsonObject();
typePart.addProperty("italic", true);
description.addProperty("translate", value + ".desc");
baseArray.add(newLine);
baseArray.add(description);
} else if (value.startsWith("stat")) {
namePart.addProperty("translate", value);
} else if (textValue.startsWith("stat")) {
namePart.addProperty("translate", textValue);
namePart.addProperty("color", "gray");
typePart.addProperty("translate", "stats.tooltip.type.statistic");
typePart.addProperty("italic", true);
@@ -1,6 +1,7 @@
package us.myles.ViaVersion.protocols.protocol1_13_1to1_13;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.data.MappingData;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.Protocol;
@@ -8,6 +9,7 @@ import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.remapper.ValueTransformer;
import us.myles.ViaVersion.api.rewriters.StatisticsRewriter;
import us.myles.ViaVersion.api.rewriters.TagRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_13_1to1_13.metadata.MetadataRewriter1_13_1To1_13;
import us.myles.ViaVersion.protocols.protocol1_13_1to1_13.packets.EntityPackets;
@@ -20,6 +22,8 @@ import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class Protocol1_13_1To1_13 extends Protocol<ClientboundPackets1_13, ClientboundPackets1_13, ServerboundPackets1_13, ServerboundPackets1_13> {
public static final MappingData MAPPINGS = new MappingData("1.13", "1.13.2", true);
public Protocol1_13_1To1_13() {
super(ClientboundPackets1_13.class, ClientboundPackets1_13.class, ServerboundPackets1_13.class, ServerboundPackets1_13.class);
}
@@ -119,46 +123,8 @@ public class Protocol1_13_1To1_13 extends Protocol<ClientboundPackets1_13, Clien
}
});
registerOutgoing(ClientboundPackets1_13.TAGS, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
int blockTagsSize = wrapper.passthrough(Type.VAR_INT); // block tags
for (int i = 0; i < blockTagsSize; i++) {
wrapper.passthrough(Type.STRING);
int[] blocks = wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE);
for (int j = 0; j < blocks.length; j++) {
blocks[j] = getNewBlockId(blocks[j]);
}
}
int itemTagsSize = wrapper.passthrough(Type.VAR_INT); // item tags
for (int i = 0; i < itemTagsSize; i++) {
wrapper.passthrough(Type.STRING);
int[] items = wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE);
for (int j = 0; j < items.length; j++) {
items[j] = InventoryPackets.getNewItemId(items[j]);
}
}
}
});
}
});
new StatisticsRewriter(this, null, null, null, id -> {
int newId = id;
if (newId > 22) {
newId += 2;
}
if (newId > 25) {
newId += 3;
}
if (newId > 40) {
newId++;
}
return newId;
}).register(ClientboundPackets1_13.STATISTICS);
new TagRewriter(this, null).register(ClientboundPackets1_13.TAGS);
new StatisticsRewriter(this, null).register(ClientboundPackets1_13.STATISTICS);
}
@Override
@@ -169,26 +135,8 @@ public class Protocol1_13_1To1_13 extends Protocol<ClientboundPackets1_13, Clien
}
}
public static int getNewBlockStateId(int blockId) {
if (blockId > 8573) {
blockId += 17;
} else if (blockId > 8463) {
blockId += 16;
} else if (blockId > 8458) {
blockId = 8470 + (blockId - 8459) * 2;
} else if (blockId > 1126) {
blockId += 1;
}
return blockId;
}
public static int getNewBlockId(final int oldBlockId) {
int blockId = oldBlockId;
if (oldBlockId >= 561) {
blockId += 5;
}
return blockId;
@Override
public MappingData getMappingData() {
return MAPPINGS;
}
}
@@ -7,6 +7,7 @@ import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_13;
import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.api.type.types.Particle;
import us.myles.ViaVersion.protocols.protocol1_13_1to1_13.Protocol1_13_1To1_13;
import us.myles.ViaVersion.protocols.protocol1_13_1to1_13.packets.InventoryPackets;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.EntityTracker1_13;
@@ -27,7 +28,7 @@ public class MetadataRewriter1_13_1To1_13 extends MetadataRewriter {
} else if (metadata.getMetaType() == MetaType1_13.BlockID) {
// Convert to new block id
int data = (int) metadata.getValue();
metadata.setValue(Protocol1_13_1To1_13.getNewBlockStateId(data));
metadata.setValue(protocol.getMappingData().getNewBlockStateId(data));
}
if (type == null) return;
@@ -35,11 +36,11 @@ public class MetadataRewriter1_13_1To1_13 extends MetadataRewriter {
if (type.isOrHasParent(Entity1_13Types.EntityType.MINECART_ABSTRACT) && metadata.getId() == 9) {
// New block format
int data = (int) metadata.getValue();
metadata.setValue(Protocol1_13_1To1_13.getNewBlockStateId(data));
}
if (type.isOrHasParent(Entity1_13Types.EntityType.ABSTRACT_ARROW) && metadata.getId() >= 7) {
metadata.setValue(protocol.getMappingData().getNewBlockStateId(data));
} else if (type.isOrHasParent(Entity1_13Types.EntityType.ABSTRACT_ARROW) && metadata.getId() >= 7) {
metadata.setId(metadata.getId() + 1); // New shooter UUID
} else if (type.is(Entity1_13Types.EntityType.AREA_EFFECT_CLOUD) && metadata.getId() == 10) {
rewriteParticle((Particle) metadata.getValue());
}
}
@@ -40,7 +40,7 @@ public class EntityPackets {
if (entType != null) {
if (entType.is(Entity1_13Types.EntityType.FALLING_BLOCK)) {
int data = wrapper.get(Type.INT, 0);
wrapper.set(Type.INT, 0, Protocol1_13_1To1_13.getNewBlockStateId(data));
wrapper.set(Type.INT, 0, protocol.getMappingData().getNewBlockStateId(data));
}
// Register Type ID
wrapper.user().get(EntityTracker1_13.class).addEntity(entityId, entType);
@@ -2,25 +2,24 @@ package us.myles.ViaVersion.protocols.protocol1_13_1to1_13.packets;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.ItemRewriter;
import us.myles.ViaVersion.api.rewriters.RecipeRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_13_1to1_13.Protocol1_13_1To1_13;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ServerboundPackets1_13;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.RecipeRewriter1_13_2;
public class InventoryPackets {
public static void register(Protocol protocol) {
public static void register(Protocol1_13_1To1_13 protocol) {
ItemRewriter itemRewriter = new ItemRewriter(protocol, InventoryPackets::toClient, InventoryPackets::toServer);
itemRewriter.registerSetCooldown(ClientboundPackets1_13.COOLDOWN, InventoryPackets::getNewItemId);
itemRewriter.registerSetSlot(ClientboundPackets1_13.SET_SLOT, Type.FLAT_ITEM);
itemRewriter.registerWindowItems(ClientboundPackets1_13.WINDOW_ITEMS, Type.FLAT_ITEM_ARRAY);
itemRewriter.registerAdvancements(ClientboundPackets1_13.ADVANCEMENTS, Type.FLAT_ITEM);
itemRewriter.registerSetCooldown(ClientboundPackets1_13.COOLDOWN);
protocol.registerOutgoing(ClientboundPackets1_13.PLUGIN_MESSAGE, new PacketRemapper() {
@Override
@@ -76,29 +75,17 @@ public class InventoryPackets {
itemRewriter.registerClickWindow(ServerboundPackets1_13.CLICK_WINDOW, Type.FLAT_ITEM);
itemRewriter.registerCreativeInvAction(ServerboundPackets1_13.CREATIVE_INVENTORY_ACTION, Type.FLAT_ITEM);
itemRewriter.registerSpawnParticle(ClientboundPackets1_13.SPAWN_PARTICLE, Type.FLAT_ITEM, Type.FLOAT);
}
public static void toClient(Item item) {
if (item == null) return;
item.setIdentifier(getNewItemId(item.getIdentifier()));
}
public static int getNewItemId(int itemId) {
if (itemId >= 443) {
return itemId + 5;
}
return itemId;
item.setIdentifier(Protocol1_13_1To1_13.MAPPINGS.getNewItemId(item.getIdentifier()));
}
public static void toServer(Item item) {
if (item == null) return;
item.setIdentifier(getOldItemId(item.getIdentifier()));
}
public static int getOldItemId(int newId) {
if (newId >= 448) {
return newId - 5;
}
return newId;
item.setIdentifier(Protocol1_13_1To1_13.MAPPINGS.getOldItemId(item.getIdentifier()));
}
}
@@ -8,7 +8,6 @@ import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.BlockRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_13_1to1_13.Protocol1_13_1To1_13;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types.Chunk1_13Type;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
@@ -16,7 +15,7 @@ import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class WorldPackets {
public static void register(Protocol protocol) {
BlockRewriter blockRewriter = new BlockRewriter(protocol, Type.POSITION, Protocol1_13_1To1_13::getNewBlockStateId, Protocol1_13_1To1_13::getNewBlockId);
BlockRewriter blockRewriter = new BlockRewriter(protocol, Type.POSITION);
protocol.registerOutgoing(ClientboundPackets1_13.CHUNK_DATA, new PacketRemapper() {
@Override
@@ -30,7 +29,7 @@ public class WorldPackets {
for (ChunkSection section : chunk.getSections()) {
if (section == null) continue;
for (int i = 0; i < section.getPaletteSize(); i++) {
section.setPaletteEntry(i, Protocol1_13_1To1_13.getNewBlockStateId(section.getPaletteEntry(i)));
section.setPaletteEntry(i, protocol.getMappingData().getNewBlockStateId(section.getPaletteEntry(i)));
}
}
}
@@ -41,7 +40,7 @@ public class WorldPackets {
blockRewriter.registerBlockAction(ClientboundPackets1_13.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_13.BLOCK_CHANGE);
blockRewriter.registerMultiBlockChange(ClientboundPackets1_13.MULTI_BLOCK_CHANGE);
blockRewriter.registerEffect(ClientboundPackets1_13.EFFECT, 1010, 2001, InventoryPackets::getNewItemId);
blockRewriter.registerEffect(ClientboundPackets1_13.EFFECT, 1010, 2001);
protocol.registerOutgoing(ClientboundPackets1_13.JOIN_GAME, new PacketRemapper() {
@Override
@@ -76,7 +75,5 @@ public class WorldPackets {
});
}
});
blockRewriter.registerSpawnParticle(ClientboundPackets1_13.SPAWN_PARTICLE, 3, 20, 27, InventoryPackets::toClient, Type.FLAT_ITEM, Type.FLOAT);
}
}
@@ -3,27 +3,26 @@ package us.myles.ViaVersion.protocols.protocol1_13to1_12_2;
import com.google.gson.JsonElement;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.chat.ComponentSerializer;
import us.myles.ViaVersion.api.rewriters.ComponentRewriter;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.ComponentRewriter1_13;
import us.myles.ViaVersion.util.GsonUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ChatRewriter {
private static final BaseComponent[] EMPTY_COMPONENTS = new BaseComponent[0];
private static final ComponentRewriter COMPONENT_REWRITER = new ComponentRewriter1_13();
// Based on https://github.com/SpigotMC/BungeeCord/blob/master/chat/src/main/java/net/md_5/bungee/api/chat/TextComponent.java
public static JsonElement fromLegacyText(String message, ChatColor defaultColor) {
List<BaseComponent> components = new ArrayList<>();
StringBuilder builder = new StringBuilder();
public static String fromLegacyTextAsString(String message, ChatColor defaultColor, boolean lore) {
TextComponent headComponent = new TextComponent();
TextComponent component = new TextComponent();
StringBuilder builder = new StringBuilder();
if (lore) {
// Workaround for all italic lore
headComponent.setItalic(false);
//TODO set first child to italics if it doesn't have a color
}
for (int i = 0; i < message.length(); i++) {
char c = message.charAt(i);
@@ -44,7 +43,7 @@ public class ChatRewriter {
component = new TextComponent(old);
old.setText(builder.toString());
builder = new StringBuilder();
components.add(old);
headComponent.addExtra(old);
}
if (ChatColor.BOLD.equals(format)) {
component.setBold(true);
@@ -61,23 +60,9 @@ public class ChatRewriter {
component = new TextComponent();
component.setColor(format);
// ViaVersion start - Items have style default to italic
component.setBold(false);
component.setItalic(false);
component.setUnderlined(false);
component.setStrikethrough(false);
component.setObfuscated(false);
// ViaVersion end
} else {
component = new TextComponent();
component.setColor(format);
// ViaVersion start- Items have style default to italic
component.setBold(false);
component.setItalic(false);
component.setUnderlined(false);
component.setStrikethrough(false);
component.setObfuscated(false);
// ViaVersion end
}
continue;
}
@@ -85,16 +70,23 @@ public class ChatRewriter {
}
component.setText(builder.toString());
components.add(component);
headComponent.addExtra(component);
final String serializedComponents = ComponentSerializer.toString(components.toArray(EMPTY_COMPONENTS));
return GsonUtil.getJsonParser().parse(serializedComponents);
return ComponentSerializer.toString(headComponent);
}
public static JsonElement fromLegacyText(String message, ChatColor defaultColor) {
return GsonUtil.getJsonParser().parse(fromLegacyTextAsString(message, defaultColor, false));
}
public static JsonElement legacyTextToJson(String legacyText) {
return fromLegacyText(legacyText, ChatColor.WHITE);
}
public static String legacyTextToJsonString(String legacyText) {
return fromLegacyTextAsString(legacyText, ChatColor.WHITE, false);
}
public static String jsonTextToLegacy(String value) {
return TextComponent.toLegacyText(ComponentSerializer.parse(value));
}
@@ -17,6 +17,7 @@ import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.remapper.ValueCreator;
import us.myles.ViaVersion.api.remapper.ValueTransformer;
import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.api.rewriters.SoundRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
@@ -25,7 +26,11 @@ import us.myles.ViaVersion.protocols.protocol1_12_1to1_12.ServerboundPackets1_12
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionData;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.providers.BlockConnectionProvider;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.providers.PacketBlockConnectionProvider;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.*;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.BlockIdData;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.RecipeData;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.StatisticData;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.StatisticMappings;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.metadata.MetadataRewriter1_13To1_12_2;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.EntityPackets;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets;
@@ -39,12 +44,18 @@ import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.TabCompleteTra
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
import us.myles.ViaVersion.util.GsonUtil;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Protocol1_13To1_12_2 extends Protocol<ClientboundPackets1_12_1, ClientboundPackets1_13, ServerboundPackets1_12_1, ServerboundPackets1_13> {
public static final MappingData MAPPINGS = new MappingData();
public Protocol1_13To1_12_2() {
super(ClientboundPackets1_12_1.class, ClientboundPackets1_13.class, ServerboundPackets1_12_1.class, ServerboundPackets1_13.class, true);
super(ClientboundPackets1_12_1.class, ClientboundPackets1_13.class, ServerboundPackets1_12_1.class, ServerboundPackets1_13.class);
}
public static final PacketHandler POS_TO_3_INT = wrapper -> {
@@ -54,58 +65,55 @@ public class Protocol1_13To1_12_2 extends Protocol<ClientboundPackets1_12_1, Cli
wrapper.write(Type.INT, position.getZ());
};
public static final PacketHandler SEND_DECLARE_COMMANDS_AND_TAGS =
new PacketHandler() { // *insert here a good name*
@Override
public void handle(PacketWrapper w) throws Exception {
// Send fake declare commands
w.create(0x11, new ValueCreator() {
@Override
public void write(PacketWrapper wrapper) {
wrapper.write(Type.VAR_INT, 2); // Size
// Write root node
wrapper.write(Type.VAR_INT, 0); // Mark as command
wrapper.write(Type.VAR_INT, 1); // 1 child
wrapper.write(Type.VAR_INT, 1); // Child is at 1
private static final PacketHandler SEND_DECLARE_COMMANDS_AND_TAGS =
w -> {
// Send fake declare commands
w.create(0x11, new ValueCreator() {
@Override
public void write(PacketWrapper wrapper) {
wrapper.write(Type.VAR_INT, 2); // Size
// Write root node
wrapper.write(Type.VAR_INT, 0); // Mark as command
wrapper.write(Type.VAR_INT, 1); // 1 child
wrapper.write(Type.VAR_INT, 1); // Child is at 1
// Write arg node
wrapper.write(Type.VAR_INT, 0x02 | 0x04 | 0x10); // Mark as command
wrapper.write(Type.VAR_INT, 0); // No children
// Extra data
wrapper.write(Type.STRING, "args"); // Arg name
wrapper.write(Type.STRING, "brigadier:string");
wrapper.write(Type.VAR_INT, 2); // Greedy
wrapper.write(Type.STRING, "minecraft:ask_server"); // Ask server
// Write arg node
wrapper.write(Type.VAR_INT, 0x02 | 0x04 | 0x10); // Mark as command
wrapper.write(Type.VAR_INT, 0); // No children
// Extra data
wrapper.write(Type.STRING, "args"); // Arg name
wrapper.write(Type.STRING, "brigadier:string");
wrapper.write(Type.VAR_INT, 2); // Greedy
wrapper.write(Type.STRING, "minecraft:ask_server"); // Ask server
wrapper.write(Type.VAR_INT, 0); // Root node index
wrapper.write(Type.VAR_INT, 0); // Root node index
}
}).send(Protocol1_13To1_12_2.class);
// Send tags packet
w.create(0x55, new ValueCreator() {
@Override
public void write(PacketWrapper wrapper) throws Exception {
wrapper.write(Type.VAR_INT, MAPPINGS.getBlockTags().size()); // block tags
for (Map.Entry<String, Integer[]> tag : MAPPINGS.getBlockTags().entrySet()) {
wrapper.write(Type.STRING, tag.getKey());
// Needs copy as other protocols may modify it
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, toPrimitive(tag.getValue()));
}
}).send(Protocol1_13To1_12_2.class);
// Send tags packet
w.create(0x55, new ValueCreator() {
@Override
public void write(PacketWrapper wrapper) throws Exception {
wrapper.write(Type.VAR_INT, MappingData.blockTags.size()); // block tags
for (Map.Entry<String, Integer[]> tag : MappingData.blockTags.entrySet()) {
wrapper.write(Type.STRING, tag.getKey());
// Needs copy as other protocols may modify it
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, toPrimitive(tag.getValue()));
}
wrapper.write(Type.VAR_INT, MappingData.itemTags.size()); // item tags
for (Map.Entry<String, Integer[]> tag : MappingData.itemTags.entrySet()) {
wrapper.write(Type.STRING, tag.getKey());
// Needs copy as other protocols may modify it
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, toPrimitive(tag.getValue()));
}
wrapper.write(Type.VAR_INT, MappingData.fluidTags.size()); // fluid tags
for (Map.Entry<String, Integer[]> tag : MappingData.fluidTags.entrySet()) {
wrapper.write(Type.STRING, tag.getKey());
// Needs copy as other protocols may modify it
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, toPrimitive(tag.getValue()));
}
wrapper.write(Type.VAR_INT, MAPPINGS.getItemTags().size()); // item tags
for (Map.Entry<String, Integer[]> tag : MAPPINGS.getItemTags().entrySet()) {
wrapper.write(Type.STRING, tag.getKey());
// Needs copy as other protocols may modify it
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, toPrimitive(tag.getValue()));
}
}).send(Protocol1_13To1_12_2.class);
}
wrapper.write(Type.VAR_INT, MAPPINGS.getFluidTags().size()); // fluid tags
for (Map.Entry<String, Integer[]> tag : MAPPINGS.getFluidTags().entrySet()) {
wrapper.write(Type.STRING, tag.getKey());
// Needs copy as other protocols may modify it
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, toPrimitive(tag.getValue()));
}
}
}).send(Protocol1_13To1_12_2.class);
};
// These are arbitrary rewrite values, it just needs an invalid color code character.
@@ -140,7 +148,7 @@ public class Protocol1_13To1_12_2 extends Protocol<ClientboundPackets1_12_1, Cli
@Override
protected void registerPackets() {
new MetadataRewriter1_13To1_12_2(this);
MetadataRewriter metadataRewriter = new MetadataRewriter1_13To1_12_2(this);
// Register grouped packet changes
EntityPackets.register(this);
@@ -330,7 +338,7 @@ public class Protocol1_13To1_12_2 extends Protocol<ClientboundPackets1_12_1, Cli
wrapper.cancel();
if (item == 383) { // Spawn egg
for (int i = 0; i < 44; i++) {
Integer newItem = MappingData.oldToNewItems.get(item << 16 | i);
Integer newItem = getMappingData().getItemMappings().get(item << 16 | i);
if (newItem != null) {
PacketWrapper packet = wrapper.create(0x18);
packet.write(Type.VAR_INT, newItem);
@@ -342,7 +350,7 @@ public class Protocol1_13To1_12_2 extends Protocol<ClientboundPackets1_12_1, Cli
}
} else {
for (int i = 0; i < 16; i++) {
int newItem = MappingData.oldToNewItems.get(item << 4 | i);
int newItem = getMappingData().getItemMappings().get(item << 4 | i);
if (newItem != -1) {
PacketWrapper packet = wrapper.create(0x18);
packet.write(Type.VAR_INT, newItem);
@@ -377,7 +385,7 @@ public class Protocol1_13To1_12_2 extends Protocol<ClientboundPackets1_12_1, Cli
int id = wrapper.get(Type.INT, 0);
int data = wrapper.get(Type.INT, 1);
if (id == 1010) { // Play record
wrapper.set(Type.INT, 1, MappingData.oldToNewItems.get(data << 4));
wrapper.set(Type.INT, 1, getMappingData().getItemMappings().get(data << 4));
} else if (id == 2001) { // Block break + block break sound
int blockId = data & 0xFFF;
int blockData = data >> 12;
@@ -679,7 +687,7 @@ public class Protocol1_13To1_12_2 extends Protocol<ClientboundPackets1_12_1, Cli
});
// New 0x4C - Stop Sound
new SoundRewriter(this, id -> MappingData.soundMappings.getNewId(id)).registerSound(ClientboundPackets1_12_1.SOUND);
new SoundRewriter(this).registerSound(ClientboundPackets1_12_1.SOUND);
registerOutgoing(ClientboundPackets1_12_1.TAB_LIST, new PacketRemapper() {
@Override
@@ -1015,8 +1023,7 @@ public class Protocol1_13To1_12_2 extends Protocol<ClientboundPackets1_12_1, Cli
}
@Override
protected void loadMappingData() {
MappingData.init();
protected void onMappingDataLoaded() {
ConnectionData.init();
RecipeData.init();
BlockIdData.init();
@@ -1086,4 +1093,9 @@ public class Protocol1_13To1_12_2 extends Protocol<ClientboundPackets1_12_1, Cli
}
return prim;
}
@Override
public MappingData getMappingData() {
return MAPPINGS;
}
}
@@ -4,7 +4,6 @@ import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.BlockFace;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import java.util.HashMap;
import java.util.HashSet;
@@ -44,7 +43,7 @@ public abstract class AbstractFenceConnectionHandler extends ConnectionHandler {
protected byte getStates(UserConnection user, Position position, int blockState) {
byte states = 0;
boolean pre1_12 = user.getProtocolInfo().getServerProtocolVersion() < ProtocolVersion.v1_12.getId();
boolean pre1_12 = user.getProtocolInfo().getServerProtocolVersion() < ProtocolVersion.v1_12.getVersion();
if (connects(BlockFace.EAST, getBlockData(user, position.getRelative(BlockFace.EAST)), pre1_12)) states |= 1;
if (connects(BlockFace.NORTH, getBlockData(user, position.getRelative(BlockFace.NORTH)), pre1_12)) states |= 2;
if (connects(BlockFace.SOUTH, getBlockData(user, position.getRelative(BlockFace.SOUTH)), pre1_12)) states |= 4;
@@ -205,7 +205,7 @@ public class ConnectionData {
Via.getPlatform().getLogger().info("Loading block connection mappings ...");
JsonObject mapping1_13 = MappingDataLoader.loadData("mapping-1.13.json", true);
JsonObject blocks1_13 = mapping1_13.getAsJsonObject("blocks");
JsonObject blocks1_13 = mapping1_13.getAsJsonObject("blockstates");
for (Entry<String, JsonElement> blockState : blocks1_13.entrySet()) {
int id = Integer.parseInt(blockState.getKey());
String key = blockState.getValue().getAsString();
@@ -2,13 +2,13 @@ package us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.prov
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.platform.providers.Provider;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
public class BlockConnectionProvider implements Provider {
public int getBlockData(UserConnection connection, int x, int y, int z) {
int oldId = getWorldBlockData(connection, x, y, z);
return MappingData.blockMappings.getNewId(oldId);
return Protocol1_13To1_12_2.MAPPINGS.getBlockMappings().getNewId(oldId);
}
public int getWorldBlockData(UserConnection connection, int x, int y, int z) {
@@ -11,6 +11,7 @@ import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.nbt.BinaryTagIO;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.rewriters.ComponentRewriter;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets;
import java.io.IOException;
@@ -103,9 +104,9 @@ public class ComponentRewriter1_13 extends ComponentRewriter {
protected void handleTranslate(JsonObject object, String translate) {
super.handleTranslate(object, translate);
String newTranslate;
newTranslate = MappingData.translateMapping.get(translate);
newTranslate = Protocol1_13To1_12_2.MAPPINGS.getTranslateMapping().get(translate);
if (newTranslate == null) {
newTranslate = MappingData.mojangTranslation.get(translate);
newTranslate = Protocol1_13To1_12_2.MAPPINGS.getMojangTranslation().get(translate);
}
if (newTranslate != null) {
object.addProperty("translate", newTranslate);
@@ -7,11 +7,11 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
import us.myles.ViaVersion.api.data.Mappings;
import us.myles.ViaVersion.util.GsonUtil;
import us.myles.ViaVersion.util.Int2IntBiMap;
import java.io.IOException;
import java.io.InputStreamReader;
@@ -20,34 +20,44 @@ import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
public class MappingData {
public static final Int2IntBiMap oldToNewItems = new Int2IntBiMap();
public static final Map<String, Integer[]> blockTags = new HashMap<>();
public static final Map<String, Integer[]> itemTags = new HashMap<>();
public static final Map<String, Integer[]> fluidTags = new HashMap<>();
public static final BiMap<Short, String> oldEnchantmentsIds = HashBiMap.create();
public static final Map<String, String> translateMapping = new HashMap<>();
public static final Map<String, String> mojangTranslation = new HashMap<>();
public static final BiMap<String, String> channelMappings = HashBiMap.create(); // 1.12->1.13
public static Mappings enchantmentMappings;
public static Mappings soundMappings;
public static Mappings blockMappings;
public class MappingData extends us.myles.ViaVersion.api.data.MappingData {
private final Map<String, Integer[]> blockTags = new HashMap<>();
private final Map<String, Integer[]> itemTags = new HashMap<>();
private final Map<String, Integer[]> fluidTags = new HashMap<>();
private final BiMap<Short, String> oldEnchantmentsIds = HashBiMap.create();
private final Map<String, String> translateMapping = new HashMap<>();
private final Map<String, String> mojangTranslation = new HashMap<>();
private final BiMap<String, String> channelMappings = HashBiMap.create(); // 1.12->1.13
private Mappings enchantmentMappings;
public static void init() {
Via.getPlatform().getLogger().info("Loading 1.12.2 -> 1.13 mappings...");
JsonObject mapping1_12 = MappingDataLoader.loadData("mapping-1.12.json", true);
JsonObject mapping1_13 = MappingDataLoader.loadData("mapping-1.13.json", true);
public MappingData() {
super("1.12", "1.13");
}
oldToNewItems.defaultReturnValue(-1);
blockMappings = new BlockMappingsShortArray(mapping1_12.getAsJsonObject("blocks"), mapping1_13.getAsJsonObject("blocks"));
MappingDataLoader.mapIdentifiers(oldToNewItems, mapping1_12.getAsJsonObject("items"), mapping1_13.getAsJsonObject("items"));
loadTags(blockTags, mapping1_13.getAsJsonObject("block_tags"));
loadTags(itemTags, mapping1_13.getAsJsonObject("item_tags"));
loadTags(fluidTags, mapping1_13.getAsJsonObject("fluid_tags"));
@Override
public void loadExtras(JsonObject oldMappings, JsonObject newMappings, JsonObject diffMappings) {
loadTags(blockTags, newMappings.getAsJsonObject("block_tags"));
loadTags(itemTags, newMappings.getAsJsonObject("item_tags"));
loadTags(fluidTags, newMappings.getAsJsonObject("fluid_tags"));
loadEnchantments(oldEnchantmentsIds, mapping1_12.getAsJsonObject("enchantments"));
enchantmentMappings = new Mappings(72, mapping1_12.getAsJsonObject("enchantments"), mapping1_13.getAsJsonObject("enchantments"));
soundMappings = new Mappings(662, mapping1_12.getAsJsonArray("sounds"), mapping1_13.getAsJsonArray("sounds"));
loadEnchantments(oldEnchantmentsIds, oldMappings.getAsJsonObject("enchantments"));
enchantmentMappings = new Mappings(72, oldMappings.getAsJsonObject("enchantments"), newMappings.getAsJsonObject("enchantments"));
// Map minecraft:snow[layers=1] of 1.12 to minecraft:snow[layers=2] in 1.13
if (Via.getConfig().isSnowCollisionFix()) {
blockMappings.getOldToNew()[1248] = 3416;
}
// Remap infested blocks, as they are instantly breakabale in 1.13+ and can't be broken by those clients on older servers
if (Via.getConfig().isInfestedBlocksFix()) {
short[] oldToNew = blockMappings.getOldToNew();
oldToNew[1552] = 1; // stone
oldToNew[1553] = 14; // cobblestone
oldToNew[1554] = 3983; // stone bricks
oldToNew[1555] = 3984; // mossy stone bricks
oldToNew[1556] = 3985; // cracked stone bricks
oldToNew[1557] = 3986; // chiseled stone bricks
}
JsonObject object = MappingDataLoader.loadFromDataDir("channelmappings-1.13.json");
if (object != null) {
@@ -94,6 +104,16 @@ public class MappingData {
}
}
@Override
protected Mappings loadFromObject(JsonObject oldMappings, JsonObject newMappings, @Nullable JsonObject diffMappings, String key) {
if (key.equals("blocks")) {
// Need to use a custom size since there are larger gaps in ids
return new Mappings(4084, oldMappings.getAsJsonObject("blocks"), newMappings.getAsJsonObject("blockstates"));
} else {
return super.loadFromObject(oldMappings, newMappings, diffMappings, key);
}
}
public static String validateNewChannel(String newId) {
if (!isValid1_13Channel(newId)) {
return null; // Not valid
@@ -110,7 +130,7 @@ public class MappingData {
return channelId.matches("([0-9a-z_.-]+):([0-9a-z_/.-]+)");
}
private static void loadTags(Map<String, Integer[]> output, JsonObject newTags) {
private void loadTags(Map<String, Integer[]> output, JsonObject newTags) {
for (Map.Entry<String, JsonElement> entry : newTags.entrySet()) {
JsonArray ids = entry.getValue().getAsJsonArray();
Integer[] idsArray = new Integer[ids.size()];
@@ -121,31 +141,41 @@ public class MappingData {
}
}
private static void loadEnchantments(Map<Short, String> output, JsonObject enchantments) {
private void loadEnchantments(Map<Short, String> output, JsonObject enchantments) {
for (Map.Entry<String, JsonElement> enchantment : enchantments.entrySet()) {
output.put(Short.parseShort(enchantment.getKey()), enchantment.getValue().getAsString());
}
}
private static class BlockMappingsShortArray extends Mappings {
public Map<String, Integer[]> getBlockTags() {
return blockTags;
}
private BlockMappingsShortArray(JsonObject mapping1_12, JsonObject mapping1_13) {
super(4084, mapping1_12, mapping1_13);
public Map<String, Integer[]> getItemTags() {
return itemTags;
}
// Map minecraft:snow[layers=1] of 1.12 to minecraft:snow[layers=2] in 1.13
if (Via.getConfig().isSnowCollisionFix()) {
oldToNew[1248] = 3416;
}
public Map<String, Integer[]> getFluidTags() {
return fluidTags;
}
// Remap infested blocks, as they are instantly breakabale in 1.13+ and can't be broken by those clients on older servers
if (Via.getConfig().isInfestedBlocksFix()) {
oldToNew[1552] = 1; // stone
oldToNew[1553] = 14; // cobblestone
oldToNew[1554] = 3983; // stone bricks
oldToNew[1555] = 3984; // mossy stone bricks
oldToNew[1556] = 3985; // cracked stone bricks
oldToNew[1557] = 3986; // chiseled stone bricks
}
}
public BiMap<Short, String> getOldEnchantmentsIds() {
return oldEnchantmentsIds;
}
public Map<String, String> getTranslateMapping() {
return translateMapping;
}
public Map<String, String> getMojangTranslation() {
return mojangTranslation;
}
public BiMap<String, String> getChannelMappings() {
return channelMappings;
}
public Mappings getEnchantmentMappings() {
return enchantmentMappings;
}
}
@@ -35,7 +35,7 @@ public class StatisticMappings {
CUSTOM_STATS.put("stat.playerKills", 26);
CUSTOM_STATS.put("stat.fishCaught", 27);
CUSTOM_STATS.put("stat.talkedToVillager", 28);
CUSTOM_STATS.put("stat.tradedWithVillage", 29);
CUSTOM_STATS.put("stat.tradedWithVillager", 29);
CUSTOM_STATS.put("stat.cakeSlicesEaten", 30);
CUSTOM_STATS.put("stat.cauldronFilled", 31);
CUSTOM_STATS.put("stat.cauldronUsed", 32);
@@ -12,7 +12,6 @@ import com.google.common.primitives.Ints;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.ItemRewriter;
@@ -35,7 +34,7 @@ import java.util.Optional;
public class InventoryPackets {
private static final String NBT_TAG_NAME = "ViaVersion|" + Protocol1_13To1_12_2.class.getSimpleName();
public static void register(Protocol protocol) {
public static void register(Protocol1_13To1_12_2 protocol) {
ItemRewriter itemRewriter = new ItemRewriter(protocol, InventoryPackets::toClient, InventoryPackets::toServer);
protocol.registerOutgoing(ClientboundPackets1_12_1.SET_SLOT, new PacketRemapper() {
@@ -69,7 +68,7 @@ public class InventoryPackets {
public void handle(PacketWrapper wrapper) throws Exception {
short property = wrapper.get(Type.SHORT, 0);
if (property >= 4 && property <= 6) { // Enchantment id
wrapper.set(Type.SHORT, 1, (short) MappingData.enchantmentMappings.getNewId(wrapper.get(Type.SHORT, 1)));
wrapper.set(Type.SHORT, 1, (short) protocol.getMappingData().getEnchantmentMappings().getNewId(wrapper.get(Type.SHORT, 1)));
}
}
});
@@ -304,7 +303,7 @@ public class InventoryPackets {
if (display.get("Name") instanceof StringTag) {
StringTag name = display.get("Name");
display.put(new StringTag(NBT_TAG_NAME + "|Name", name.getValue()));
name.setValue(ChatRewriter.legacyTextToJson(name.getValue()).toString());
name.setValue(ChatRewriter.legacyTextToJsonString(name.getValue()));
}
}
// ench is now Enchantments and now uses identifiers
@@ -315,7 +314,7 @@ public class InventoryPackets {
if (enchEntry instanceof CompoundTag) {
CompoundTag enchantmentEntry = new CompoundTag("");
short oldId = ((Number) ((CompoundTag) enchEntry).get("id").getValue()).shortValue();
String newId = MappingData.oldEnchantmentsIds.get(oldId);
String newId = Protocol1_13To1_12_2.MAPPINGS.getOldEnchantmentsIds().get(oldId);
if (newId == null) {
newId = "viaversion:legacy/" + oldId;
}
@@ -334,7 +333,7 @@ public class InventoryPackets {
if (enchEntry instanceof CompoundTag) {
CompoundTag enchantmentEntry = new CompoundTag("");
short oldId = ((Number) ((CompoundTag) enchEntry).get("id").getValue()).shortValue();
String newId = MappingData.oldEnchantmentsIds.get(oldId);
String newId = Protocol1_13To1_12_2.MAPPINGS.getOldEnchantmentsIds().get(oldId);
if (newId == null) {
newId = "viaversion:legacy/" + oldId;
}
@@ -420,14 +419,14 @@ public class InventoryPackets {
}
}
if (!MappingData.oldToNewItems.containsKey(rawId)) {
if (!Protocol1_13To1_12_2.MAPPINGS.getItemMappings().containsKey(rawId)) {
if (!isDamageable(item.getIdentifier()) && item.getIdentifier() != 358) { // Map
if (tag == null) item.setTag(tag = new CompoundTag("tag"));
tag.put(new IntTag(NBT_TAG_NAME, originalId)); // Data will be lost, saving original id
}
if (item.getIdentifier() == 31 && item.getData() == 0) { // Shrub was removed
rawId = 32 << 4; // Dead Bush
} else if (MappingData.oldToNewItems.containsKey(rawId & ~0xF)) {
} else if (Protocol1_13To1_12_2.MAPPINGS.getItemMappings().containsKey(rawId & ~0xF)) {
rawId &= ~0xF; // Remove data
} else {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
@@ -437,7 +436,7 @@ public class InventoryPackets {
}
}
item.setIdentifier(MappingData.oldToNewItems.get(rawId));
item.setIdentifier(Protocol1_13To1_12_2.MAPPINGS.getItemMappings().get(rawId));
item.setData((short) 0);
}
@@ -463,7 +462,7 @@ public class InventoryPackets {
case "bungeecord:main":
return null;
default:
String mappedChannel = MappingData.channelMappings.get(old);
String mappedChannel = Protocol1_13To1_12_2.MAPPINGS.getChannelMappings().get(old);
if (mappedChannel != null) return mappedChannel;
return MappingData.isValid1_13Channel(old) ? old : null;
}
@@ -489,7 +488,7 @@ public class InventoryPackets {
}
if (rawId == null) {
int oldId = MappingData.oldToNewItems.inverse().get(item.getIdentifier());
int oldId = Protocol1_13To1_12_2.MAPPINGS.getItemMappings().inverse().get(item.getIdentifier());
if (oldId != -1) {
// Handle spawn eggs
Optional<String> eggEntityId = SpawnEggRewriter.getEntityId(oldId);
@@ -576,7 +575,7 @@ public class InventoryPackets {
if (enchantmentEntry instanceof CompoundTag) {
CompoundTag enchEntry = new CompoundTag("");
String newId = (String) ((CompoundTag) enchantmentEntry).get("id").getValue();
Short oldId = MappingData.oldEnchantmentsIds.inverse().get(newId);
Short oldId = Protocol1_13To1_12_2.MAPPINGS.getOldEnchantmentsIds().inverse().get(newId);
if (oldId == null && newId.startsWith("viaversion:legacy/")) {
oldId = Short.valueOf(newId.substring(18));
}
@@ -602,7 +601,7 @@ public class InventoryPackets {
if (enchantmentEntry instanceof CompoundTag) {
CompoundTag enchEntry = new CompoundTag("");
String newId = (String) ((CompoundTag) enchantmentEntry).get("id").getValue();
Short oldId = MappingData.oldEnchantmentsIds.inverse().get(newId);
Short oldId = Protocol1_13To1_12_2.MAPPINGS.getOldEnchantmentsIds().inverse().get(newId);
if (oldId == null && newId.startsWith("viaversion:legacy/")) {
oldId = Short.valueOf(newId.substring(18));
}
@@ -695,7 +694,7 @@ public class InventoryPackets {
case "bungeecord:main":
return "BungeeCord";
default:
String mappedChannel = MappingData.channelMappings.inverse().get(newId);
String mappedChannel = Protocol1_13To1_12_2.MAPPINGS.getChannelMappings().inverse().get(newId);
if (mappedChannel != null) return mappedChannel;
return newId.length() > 20 ? newId.substring(0, 20) : newId;
}
@@ -19,7 +19,6 @@ import us.myles.ViaVersion.protocols.protocol1_12_1to1_12.ClientboundPackets1_12
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionData;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionHandler;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.NamedSoundRewriter;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.ParticleRewriter;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.providers.BlockEntityProvider;
@@ -535,11 +534,11 @@ public class WorldPackets {
if (oldId < 0) {
oldId = 0; // Some plugins use negative numbers to clear blocks, remap them to air.
}
int newId = MappingData.blockMappings.getNewId(oldId);
int newId = Protocol1_13To1_12_2.MAPPINGS.getBlockMappings().getNewId(oldId);
if (newId != -1) {
return newId;
}
newId = MappingData.blockMappings.getNewId(oldId & ~0xF); // Remove data
newId = Protocol1_13To1_12_2.MAPPINGS.getBlockMappings().getNewId(oldId & ~0xF); // Remove data
if (newId != -1) {
if (!Via.getConfig().isSuppressConversionWarnings() || Via.getManager().isDebug()) {
Via.getPlatform().getLogger().warning("Missing block " + oldId);
@@ -55,7 +55,7 @@ public class BannerHandler implements BlockEntityProvider.BlockEntityHandler {
Tag name = tag.get("CustomName");
if (name instanceof StringTag) {
((StringTag) name).setValue(ChatRewriter.legacyTextToJson(((StringTag) name).getValue()).toString());
((StringTag) name).setValue(ChatRewriter.legacyTextToJsonString(((StringTag) name).getValue()));
}
return blockId;
@@ -14,7 +14,7 @@ public class CommandBlockHandler implements BlockEntityProvider.BlockEntityHandl
public int transform(UserConnection user, CompoundTag tag) {
Tag name = tag.get("CustomName");
if (name instanceof StringTag) {
((StringTag) name).setValue(ChatRewriter.legacyTextToJson(((StringTag) name).getValue()).toString());
((StringTag) name).setValue(ChatRewriter.legacyTextToJsonString(((StringTag) name).getValue()));
}
Tag out = tag.get("LastOutput");
if (out instanceof StringTag) {
@@ -6,7 +6,7 @@ import us.myles.ViaVersion.api.data.StoredObject;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.Protocol1_13To1_12_2;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.WorldPackets;
import java.lang.reflect.Constructor;
@@ -30,7 +30,7 @@ public class BlockConnectionStorage extends StoredObject {
Arrays.fill(REVERSE_BLOCK_MAPPINGS, (short) -1);
for (int i = 0; i < 4096; i++) {
int newBlock = MappingData.blockMappings.getNewId(i);
int newBlock = Protocol1_13To1_12_2.MAPPINGS.getBlockMappings().getNewId(i);
if (newBlock != -1) {
REVERSE_BLOCK_MAPPINGS[newBlock] = (short) i;
}
@@ -2,6 +2,7 @@ package us.myles.ViaVersion.protocols.protocol1_14_1to1_14;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.protocols.protocol1_14_1to1_14.metadata.MetadataRewriter1_14_1To1_14;
import us.myles.ViaVersion.protocols.protocol1_14_1to1_14.packets.EntityPackets;
import us.myles.ViaVersion.protocols.protocol1_14_1to1_14.storage.EntityTracker1_14_1;
@@ -16,7 +17,7 @@ public class Protocol1_14_1To1_14 extends Protocol<ClientboundPackets1_14, Clien
@Override
protected void registerPackets() {
new MetadataRewriter1_14_1To1_14(this);
MetadataRewriter metadataRewriter = new MetadataRewriter1_14_1To1_14(this);
EntityPackets.register(this);
}
@@ -1,12 +1,12 @@
package us.myles.ViaVersion.protocols.protocol1_14to1_13_2;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.ComponentRewriter;
import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.api.rewriters.SoundRewriter;
import us.myles.ViaVersion.api.rewriters.StatisticsRewriter;
import us.myles.ViaVersion.api.type.Type;
@@ -24,22 +24,23 @@ import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
public class Protocol1_14To1_13_2 extends Protocol<ClientboundPackets1_13, ClientboundPackets1_14, ServerboundPackets1_13, ServerboundPackets1_14> {
public static final MappingData MAPPINGS = new MappingData();
public Protocol1_14To1_13_2() {
super(ClientboundPackets1_13.class, ClientboundPackets1_14.class, ServerboundPackets1_13.class, ServerboundPackets1_14.class, true);
super(ClientboundPackets1_13.class, ClientboundPackets1_14.class, ServerboundPackets1_13.class, ServerboundPackets1_14.class);
}
@Override
protected void registerPackets() {
MetadataRewriter1_14To1_13_2 metadataRewriter = new MetadataRewriter1_14To1_13_2(this);
MetadataRewriter metadataRewriter = new MetadataRewriter1_14To1_13_2(this);
InventoryPackets.register(this);
EntityPackets.register(this);
WorldPackets.register(this);
PlayerPackets.register(this);
new SoundRewriter(this, id -> MappingData.soundMappings.getNewId(id)).registerSound(ClientboundPackets1_13.SOUND);
new StatisticsRewriter(this, Protocol1_14To1_13_2::getNewBlockId,
InventoryPackets::getNewItemId, metadataRewriter::getNewEntityId, id -> MappingData.statisticsMappings.getNewId(id)).register(ClientboundPackets1_13.STATISTICS);
new SoundRewriter(this).registerSound(ClientboundPackets1_13.SOUND);
new StatisticsRewriter(this, metadataRewriter::getNewEntityId).register(ClientboundPackets1_13.STATISTICS);
ComponentRewriter componentRewriter = new ComponentRewriter1_14(this);
componentRewriter.registerChatMessage(ClientboundPackets1_13.CHAT_MESSAGE);
@@ -56,21 +57,21 @@ public class Protocol1_14To1_13_2 extends Protocol<ClientboundPackets1_13, Clien
wrapper.passthrough(Type.STRING);
int[] blockIds = wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE);
for (int j = 0; j < blockIds.length; j++) {
blockIds[j] = getNewBlockId(blockIds[j]);
blockIds[j] = getMappingData().getNewBlockId(blockIds[j]);
}
}
// Minecraft crashes if we not send signs tags
wrapper.write(Type.STRING, "minecraft:signs");
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{
getNewBlockId(150), getNewBlockId(155)
getMappingData().getNewBlockId(150), getMappingData().getNewBlockId(155)
});
wrapper.write(Type.STRING, "minecraft:wall_signs");
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{
getNewBlockId(155)
getMappingData().getNewBlockId(155)
});
wrapper.write(Type.STRING, "minecraft:standing_signs");
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{
getNewBlockId(150)
getMappingData().getNewBlockId(150)
});
// Fences and walls tags - used for block connections
wrapper.write(Type.STRING, "minecraft:fences");
@@ -85,13 +86,13 @@ public class Protocol1_14To1_13_2 extends Protocol<ClientboundPackets1_13, Clien
wrapper.passthrough(Type.STRING);
int[] itemIds = wrapper.passthrough(Type.VAR_INT_ARRAY_PRIMITIVE);
for (int j = 0; j < itemIds.length; j++) {
itemIds[j] = InventoryPackets.getNewItemId(itemIds[j]);
itemIds[j] = getMappingData().getNewItemId(itemIds[j]);
}
}
// Should fix fuel shift clicking
wrapper.write(Type.STRING, "minecraft:signs");
wrapper.write(Type.VAR_INT_ARRAY_PRIMITIVE, new int[]{
InventoryPackets.getNewItemId(541)
getMappingData().getNewItemId(541)
});
// Arrows tag (used by bow)
wrapper.write(Type.STRING, "minecraft:arrows");
@@ -116,29 +117,10 @@ public class Protocol1_14To1_13_2 extends Protocol<ClientboundPackets1_13, Clien
}
@Override
protected void loadMappingData() {
MappingData.init();
WorldPackets.air = MappingData.blockStateMappings.getNewId(0);
WorldPackets.voidAir = MappingData.blockStateMappings.getNewId(8591);
WorldPackets.caveAir = MappingData.blockStateMappings.getNewId(8592);
}
public static int getNewBlockStateId(int id) {
int newId = MappingData.blockStateMappings.getNewId(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.14 blockstate for 1.13.2 blockstate " + id);
return 0;
}
return newId;
}
public static int getNewBlockId(int id) {
int newId = MappingData.blockMappings.getNewId(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.14 block for 1.13.2 block " + id);
return 0;
}
return newId;
protected void onMappingDataLoaded() {
WorldPackets.air = getMappingData().getBlockStateMappings().getNewId(0);
WorldPackets.voidAir = getMappingData().getBlockStateMappings().getNewId(8591);
WorldPackets.caveAir = getMappingData().getBlockStateMappings().getNewId(8592);
}
@Override
@@ -148,4 +130,9 @@ public class Protocol1_14To1_13_2 extends Protocol<ClientboundPackets1_13, Clien
userConnection.put(new ClientWorld(userConnection));
}
}
@Override
public MappingData getMappingData() {
return MAPPINGS;
}
}
@@ -7,34 +7,21 @@ import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
import us.myles.ViaVersion.api.data.Mappings;
import us.myles.ViaVersion.util.Int2IntBiMap;
import java.util.HashMap;
import java.util.Map;
public class MappingData {
public static final Int2IntBiMap oldToNewItems = new Int2IntBiMap();
public static Mappings blockStateMappings;
public static Mappings blockMappings;
public static Mappings soundMappings;
public static Mappings statisticsMappings;
public static IntSet motionBlocking;
public static IntSet nonFullBlocks;
public class MappingData extends us.myles.ViaVersion.api.data.MappingData {
private IntSet motionBlocking;
private IntSet nonFullBlocks;
public static void init() {
Via.getPlatform().getLogger().info("Loading 1.13.2 -> 1.14 mappings...");
JsonObject mapping1_13_2 = MappingDataLoader.loadData("mapping-1.13.2.json", true);
JsonObject mapping1_14 = MappingDataLoader.loadData("mapping-1.14.json", true);
public MappingData() {
super("1.13.2", "1.14");
}
oldToNewItems.defaultReturnValue(-1);
blockStateMappings = new Mappings(mapping1_13_2.getAsJsonObject("blockstates"), mapping1_14.getAsJsonObject("blockstates"));
blockMappings = new Mappings(mapping1_13_2.getAsJsonObject("blocks"), mapping1_14.getAsJsonObject("blocks"));
MappingDataLoader.mapIdentifiers(oldToNewItems, mapping1_13_2.getAsJsonObject("items"), mapping1_14.getAsJsonObject("items"));
soundMappings = new Mappings(mapping1_13_2.getAsJsonArray("sounds"), mapping1_14.getAsJsonArray("sounds"));
statisticsMappings = new Mappings(mapping1_13_2.getAsJsonArray("statistics"), mapping1_14.getAsJsonArray("statistics"));
JsonObject blockStates = mapping1_14.getAsJsonObject("blockstates");
@Override
public void loadExtras(JsonObject oldMappings, JsonObject newMappings, JsonObject diffMappings) {
JsonObject blockStates = newMappings.getAsJsonObject("blockstates");
Map<String, Integer> blockStateMap = new HashMap<>(blockStates.entrySet().size());
for (Map.Entry<String, JsonElement> entry : blockStates.entrySet()) {
blockStateMap.put(entry.getValue().getAsString(), Integer.parseInt(entry.getKey()));
@@ -42,23 +29,24 @@ public class MappingData {
JsonObject heightMapData = MappingDataLoader.loadData("heightMapData-1.14.json");
JsonArray motionBlocking = heightMapData.getAsJsonArray("MOTION_BLOCKING");
MappingData.motionBlocking = new IntOpenHashSet(motionBlocking.size(), 1F);
this.motionBlocking = new IntOpenHashSet(motionBlocking.size(), 1F);
for (JsonElement blockState : motionBlocking) {
String key = blockState.getAsString();
Integer id = blockStateMap.get(key);
if (id == null) {
Via.getPlatform().getLogger().warning("Unknown blockstate " + key + " :(");
} else {
MappingData.motionBlocking.add(id.intValue());
this.motionBlocking.add(id.intValue());
}
}
if (Via.getConfig().isNonFullBlockLightFix()) {
nonFullBlocks = new IntOpenHashSet(1611, 1F);
for (Map.Entry<String, JsonElement> blockstates : mapping1_13_2.getAsJsonObject("blockstates").entrySet()) {
for (Map.Entry<String, JsonElement> blockstates : oldMappings.getAsJsonObject("blockstates").entrySet()) {
final String state = blockstates.getValue().getAsString();
if (state.contains("_slab") || state.contains("_stairs") || state.contains("_wall["))
if (state.contains("_slab") || state.contains("_stairs") || state.contains("_wall[")) {
nonFullBlocks.add(blockStateMappings.getNewId(Integer.parseInt(blockstates.getKey())));
}
}
nonFullBlocks.add(blockStateMappings.getNewId(8163)); // grass path
for (int i = 3060; i <= 3067; i++) { // farmland
@@ -66,4 +54,12 @@ public class MappingData {
}
}
}
public IntSet getMotionBlocking() {
return motionBlocking;
}
public IntSet getNonFullBlocks() {
return nonFullBlocks;
}
}
@@ -38,7 +38,7 @@ public class MetadataRewriter1_14To1_13_2 extends MetadataRewriter {
} else if (metadata.getMetaType() == MetaType1_14.BlockID) {
// Convert to new block id
int data = (int) metadata.getValue();
metadata.setValue(Protocol1_14To1_13_2.getNewBlockStateId(data));
metadata.setValue(protocol.getMappingData().getNewBlockStateId(data));
}
if (type == null) return;
@@ -95,7 +95,7 @@ public class MetadataRewriter1_14To1_13_2 extends MetadataRewriter {
if (metadata.getId() == 10) {
// New block format
int data = (int) metadata.getValue();
metadata.setValue(Protocol1_14To1_13_2.getNewBlockStateId(data));
metadata.setValue(protocol.getMappingData().getNewBlockStateId(data));
}
} else if (type.is(Entity1_14Types.EntityType.HORSE)) {
if (metadata.getId() == 18) {
@@ -104,11 +104,11 @@ public class MetadataRewriter1_14To1_13_2 extends MetadataRewriter {
int armorType = (int) metadata.getValue();
Item armorItem = null;
if (armorType == 1) { //iron armor
armorItem = new Item(InventoryPackets.getNewItemId(727), (byte) 1, (short) 0, null);
armorItem = new Item(protocol.getMappingData().getNewItemId(727), (byte) 1, (short) 0, null);
} else if (armorType == 2) { //gold armor
armorItem = new Item(InventoryPackets.getNewItemId(728), (byte) 1, (short) 0, null);
armorItem = new Item(protocol.getMappingData().getNewItemId(728), (byte) 1, (short) 0, null);
} else if (armorType == 3) { //diamond armor
armorItem = new Item(InventoryPackets.getNewItemId(729), (byte) 1, (short) 0, null);
armorItem = new Item(protocol.getMappingData().getNewItemId(729), (byte) 1, (short) 0, null);
}
PacketWrapper equipmentPacket = new PacketWrapper(0x46, null, connection);
@@ -148,8 +148,7 @@ public class MetadataRewriter1_14To1_13_2 extends MetadataRewriter {
}
} else if (type.is(Entity1_14Types.EntityType.AREA_EFFECT_CLOUD)) {
if (metadata.getId() == 10) {
Particle particle = (Particle) metadata.getValue();
particle.setId(getNewParticleId(particle.getId()));
rewriteParticle((Particle) metadata.getValue());
}
}
@@ -224,23 +223,4 @@ public class MetadataRewriter1_14To1_13_2 extends MetadataRewriter {
}
return pose;
}
public static int getNewParticleId(int id) {
if (id >= 10) {
id += 2; // new lava drips 10, 11
}
if (id >= 13) {
id += 1; // new water drip 11 -> 13
}
if (id >= 27) {
id += 1; // new 24 -> 27
}
if (id >= 29) {
id += 1; // skip new short happy villager
}
if (id >= 44) {
id += 1; // new 39 -> 44
}
return id;
}
}
@@ -55,7 +55,7 @@ public class EntityPackets {
if (type1_14 != null) {
int data = wrapper.get(Type.INT, 0);
if (type1_14.is(Entity1_14Types.EntityType.FALLING_BLOCK)) {
wrapper.set(Type.INT, 0, Protocol1_14To1_13_2.getNewBlockStateId(data));
wrapper.set(Type.INT, 0, protocol.getMappingData().getNewBlockStateId(data));
} else if (type1_14.is(Entity1_14Types.EntityType.MINECART)) {
// default is 0 = rideable minecart
switch (data) {
@@ -1,6 +1,5 @@
package us.myles.ViaVersion.protocols.protocol1_14to1_13_2.packets;
import com.github.steveice10.opennbt.conversion.ConverterRegistry;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import com.github.steveice10.opennbt.tag.builtin.DoubleTag;
import com.github.steveice10.opennbt.tag.builtin.ListTag;
@@ -9,6 +8,7 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.google.common.collect.Sets;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.md_5.bungee.api.ChatColor;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.minecraft.item.Item;
@@ -24,7 +24,6 @@ import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.RecipeRewriter1_13_2;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.Protocol1_14To1_13_2;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.ServerboundPackets1_14;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.storage.EntityTracker1_14;
import java.util.Set;
@@ -47,7 +46,7 @@ public class InventoryPackets {
public static void register(Protocol protocol) {
ItemRewriter itemRewriter = new ItemRewriter(protocol, InventoryPackets::toClient, InventoryPackets::toServer);
itemRewriter.registerSetCooldown(ClientboundPackets1_13.COOLDOWN, InventoryPackets::getNewItemId);
itemRewriter.registerSetCooldown(ClientboundPackets1_13.COOLDOWN);
itemRewriter.registerAdvancements(ClientboundPackets1_13.ADVANCEMENTS, Type.FLAT_VAR_INT_ITEM);
protocol.registerOutgoing(ClientboundPackets1_13.OPEN_WINDOW, null, new PacketRemapper() {
@@ -230,76 +229,58 @@ public class InventoryPackets {
});
itemRewriter.registerCreativeInvAction(ServerboundPackets1_14.CREATIVE_INVENTORY_ACTION, Type.FLAT_VAR_INT_ITEM);
itemRewriter.registerSpawnParticle(ClientboundPackets1_13.SPAWN_PARTICLE, Type.FLAT_VAR_INT_ITEM, Type.FLOAT);
}
public static void toClient(Item item) {
if (item == null) return;
item.setIdentifier(getNewItemId(item.getIdentifier()));
item.setIdentifier(Protocol1_14To1_13_2.MAPPINGS.getNewItemId(item.getIdentifier()));
CompoundTag tag;
if ((tag = item.getTag()) != null) {
// Display Lore now uses JSON
Tag displayTag = tag.get("display");
if (displayTag instanceof CompoundTag) {
CompoundTag display = (CompoundTag) displayTag;
Tag loreTag = display.get("Lore");
if (loreTag instanceof ListTag) {
ListTag lore = (ListTag) loreTag;
display.put(ConverterRegistry.convertToTag(NBT_TAG_NAME + "|Lore", ConverterRegistry.convertToValue(lore)));
for (Tag loreEntry : lore) {
if (loreEntry instanceof StringTag) {
((StringTag) loreEntry).setValue(ChatRewriter.legacyTextToJson(((StringTag) loreEntry).getValue()).toString());
}
if (item.getTag() == null) return;
// Display Lore now uses JSON
Tag displayTag = item.getTag().get("display");
if (displayTag instanceof CompoundTag) {
CompoundTag display = (CompoundTag) displayTag;
Tag loreTag = display.get("Lore");
if (loreTag instanceof ListTag) {
ListTag lore = (ListTag) loreTag;
display.put(new ListTag(NBT_TAG_NAME + "|Lore", lore.clone().getValue())); // Save old lore
for (Tag loreEntry : lore) {
if (loreEntry instanceof StringTag) {
String jsonText = ChatRewriter.fromLegacyTextAsString(((StringTag) loreEntry).getValue(), ChatColor.WHITE, true);
((StringTag) loreEntry).setValue(jsonText);
}
}
}
}
}
public static int getNewItemId(int id) {
int newId = MappingData.oldToNewItems.get(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.14 item for 1.13.2 item " + id);
return 1;
}
return newId;
}
public static void toServer(Item item) {
if (item == null) return;
item.setIdentifier(getOldItemId(item.getIdentifier()));
item.setIdentifier(Protocol1_14To1_13_2.MAPPINGS.getOldItemId(item.getIdentifier()));
CompoundTag tag;
if ((tag = item.getTag()) != null) {
// Display Name now uses JSON
Tag displayTag = tag.get("display");
if (displayTag instanceof CompoundTag) {
CompoundTag display = (CompoundTag) displayTag;
Tag loreTag = display.get("Lore");
if (loreTag instanceof ListTag) {
ListTag lore = (ListTag) loreTag;
ListTag via = display.get(NBT_TAG_NAME + "|Lore");
if (via != null) {
display.put(ConverterRegistry.convertToTag("Lore", ConverterRegistry.convertToValue(via)));
} else {
for (Tag loreEntry : lore) {
if (loreEntry instanceof StringTag) {
((StringTag) loreEntry).setValue(
ChatRewriter.jsonTextToLegacy(
((StringTag) loreEntry).getValue()
)
);
}
if (item.getTag() == null) return;
// Display Name now uses JSON
Tag displayTag = item.getTag().get("display");
if (displayTag instanceof CompoundTag) {
CompoundTag display = (CompoundTag) displayTag;
Tag loreTag = display.get("Lore");
if (loreTag instanceof ListTag) {
ListTag lore = (ListTag) loreTag;
ListTag savedLore = display.remove(NBT_TAG_NAME + "|Lore");
if (savedLore != null) {
display.put(new ListTag("Lore", savedLore.getValue()));
} else {
for (Tag loreEntry : lore) {
if (loreEntry instanceof StringTag) {
((StringTag) loreEntry).setValue(ChatRewriter.jsonTextToLegacy(((StringTag) loreEntry).getValue()));
}
}
display.remove(NBT_TAG_NAME + "|Lore");
}
}
}
}
public static int getOldItemId(int id) {
int oldId = MappingData.oldToNewItems.inverse().get(id);
return oldId != -1 ? oldId : 1;
}
}
}
@@ -9,7 +9,6 @@ import us.myles.ViaVersion.api.minecraft.BlockFace;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.minecraft.chunks.NibbleArray;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.remapper.ValueCreator;
@@ -18,8 +17,6 @@ import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.types.Chunk1_13Type;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.Protocol1_14To1_13_2;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.metadata.MetadataRewriter1_14To1_13_2;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.storage.EntityTracker1_14;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.types.Chunk1_14Type;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
@@ -38,8 +35,8 @@ public class WorldPackets {
Arrays.fill(FULL_LIGHT, (byte) 0xff);
}
public static void register(final Protocol protocol) {
BlockRewriter blockRewriter = new BlockRewriter(protocol, null, Protocol1_14To1_13_2::getNewBlockStateId, Protocol1_14To1_13_2::getNewBlockId);
public static void register(Protocol1_14To1_13_2 protocol) {
BlockRewriter blockRewriter = new BlockRewriter(protocol, null);
protocol.registerOutgoing(ClientboundPackets1_13.BLOCK_BREAK_ANIMATION, new PacketRemapper() {
@Override
@@ -65,7 +62,7 @@ public class WorldPackets {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.set(Type.VAR_INT, 0, Protocol1_14To1_13_2.getNewBlockId(wrapper.get(Type.VAR_INT, 0)));
wrapper.set(Type.VAR_INT, 0, protocol.getMappingData().getNewBlockId(wrapper.get(Type.VAR_INT, 0)));
}
});
}
@@ -80,7 +77,7 @@ public class WorldPackets {
public void handle(PacketWrapper wrapper) throws Exception {
int id = wrapper.get(Type.VAR_INT, 0);
wrapper.set(Type.VAR_INT, 0, Protocol1_14To1_13_2.getNewBlockStateId(id));
wrapper.set(Type.VAR_INT, 0, protocol.getMappingData().getNewBlockStateId(id));
}
});
}
@@ -144,7 +141,7 @@ public class WorldPackets {
boolean hasBlock = false;
for (int i = 0; i < section.getPaletteSize(); i++) {
int old = section.getPaletteEntry(i);
int newId = Protocol1_14To1_13_2.getNewBlockStateId(old);
int newId = protocol.getMappingData().getNewBlockStateId(old);
if (!hasBlock && newId != air && newId != voidAir && newId != caveAir) { // air, void_air, cave_air
hasBlock = true;
}
@@ -164,12 +161,12 @@ public class WorldPackets {
nonAirBlockCount++;
worldSurface[x + z * 16] = y + s * 16 + 1; // +1 (top of the block)
}
if (MappingData.motionBlocking.contains(id)) {
if (protocol.getMappingData().getMotionBlocking().contains(id)) {
motionBlocking[x + z * 16] = y + s * 16 + 1; // +1 (top of the block)
}
// Manually update light for non full blocks (block light must not be sent)
if (Via.getConfig().isNonFullBlockLightFix() && MappingData.nonFullBlocks.contains(id)) {
if (Via.getConfig().isNonFullBlockLightFix() && protocol.getMappingData().getNonFullBlocks().contains(id)) {
setNonFullLight(chunk, section, s, x, y, z);
}
}
@@ -265,18 +262,15 @@ public class WorldPackets {
int id = wrapper.get(Type.INT, 0);
int data = wrapper.get(Type.INT, 1);
if (id == 1010) { // Play record
wrapper.set(Type.INT, 1, InventoryPackets.getNewItemId(data));
wrapper.set(Type.INT, 1, protocol.getMappingData().getNewItemId(data));
} else if (id == 2001) { // Block break + block break sound
wrapper.set(Type.INT, 1, Protocol1_14To1_13_2.getNewBlockStateId(data));
wrapper.set(Type.INT, 1, protocol.getMappingData().getNewBlockStateId(data));
}
}
});
}
});
blockRewriter.registerSpawnParticle(ClientboundPackets1_13.SPAWN_PARTICLE, 3, 20, 27,
MetadataRewriter1_14To1_13_2::getNewParticleId, InventoryPackets::toClient, Type.FLAT_VAR_INT_ITEM, Type.FLOAT);
protocol.registerOutgoing(ClientboundPackets1_13.JOIN_GAME, new PacketRemapper() {
@Override
public void registerMap() {
@@ -1,9 +1,9 @@
package us.myles.ViaVersion.protocols.protocol1_15to1_14_4;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.api.rewriters.RegistryType;
import us.myles.ViaVersion.api.rewriters.SoundRewriter;
import us.myles.ViaVersion.api.rewriters.StatisticsRewriter;
@@ -21,27 +21,27 @@ import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.storage.EntityTracker1
public class Protocol1_15To1_14_4 extends Protocol<ClientboundPackets1_14, ClientboundPackets1_15, ServerboundPackets1_14, ServerboundPackets1_14> {
public static final MappingData MAPPINGS = new MappingData();
private TagRewriter tagRewriter;
public Protocol1_15To1_14_4() {
super(ClientboundPackets1_14.class, ClientboundPackets1_15.class, ServerboundPackets1_14.class, ServerboundPackets1_14.class, true);
super(ClientboundPackets1_14.class, ClientboundPackets1_15.class, ServerboundPackets1_14.class, ServerboundPackets1_14.class);
}
@Override
protected void registerPackets() {
MetadataRewriter1_15To1_14_4 metadataRewriter = new MetadataRewriter1_15To1_14_4(this);
MetadataRewriter metadataRewriter = new MetadataRewriter1_15To1_14_4(this);
EntityPackets.register(this);
PlayerPackets.register(this);
WorldPackets.register(this);
InventoryPackets.register(this);
SoundRewriter soundRewriter = new SoundRewriter(this, id -> MappingData.soundMappings.getNewId(id));
SoundRewriter soundRewriter = new SoundRewriter(this);
soundRewriter.registerSound(ClientboundPackets1_14.ENTITY_SOUND); // Entity Sound Effect (added somewhere in 1.14)
soundRewriter.registerSound(ClientboundPackets1_14.SOUND);
new StatisticsRewriter(this, Protocol1_15To1_14_4::getNewBlockId, InventoryPackets::getNewItemId,
metadataRewriter::getNewEntityId, id -> MappingData.statisticsMappings.getNewId(id)).register(ClientboundPackets1_14.STATISTICS);
new StatisticsRewriter(this, metadataRewriter::getNewEntityId).register(ClientboundPackets1_14.STATISTICS);
registerIncoming(ServerboundPackets1_14.EDIT_BOOK, new PacketRemapper() {
@Override
@@ -50,14 +50,12 @@ public class Protocol1_15To1_14_4 extends Protocol<ClientboundPackets1_14, Clien
}
});
tagRewriter = new TagRewriter(this, Protocol1_15To1_14_4::getNewBlockId, InventoryPackets::getNewItemId, EntityPackets::getNewEntityId);
tagRewriter = new TagRewriter(this, EntityPackets::getNewEntityId);
tagRewriter.register(ClientboundPackets1_14.TAGS);
}
@Override
protected void loadMappingData() {
MappingData.init();
protected void onMappingDataLoaded() {
int[] shulkerBoxes = new int[17];
int shulkerBoxOffset = 501;
for (int i = 0; i < 17; i++) {
@@ -66,26 +64,13 @@ public class Protocol1_15To1_14_4 extends Protocol<ClientboundPackets1_14, Clien
tagRewriter.addTag(RegistryType.BLOCK, "minecraft:shulker_boxes", shulkerBoxes);
}
public static int getNewBlockStateId(int id) {
int newId = MappingData.blockStateMappings.getNewId(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.15 blockstate for 1.14.4 blockstate " + id);
return 0;
}
return newId;
}
public static int getNewBlockId(int id) {
int newId = MappingData.blockMappings.getNewId(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.15 block for 1.14.4 block " + id);
return 0;
}
return newId;
}
@Override
public void init(UserConnection userConnection) {
userConnection.put(new EntityTracker1_15(userConnection));
}
@Override
public MappingData getMappingData() {
return MAPPINGS;
}
}
@@ -1,29 +1,22 @@
package us.myles.ViaVersion.protocols.protocol1_15to1_14_4.data;
import com.google.gson.JsonObject;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
import org.jetbrains.annotations.Nullable;
import us.myles.ViaVersion.api.data.Mappings;
import us.myles.ViaVersion.util.Int2IntBiMap;
public class MappingData {
public static Int2IntBiMap oldToNewItems = new Int2IntBiMap();
public static Mappings blockMappings;
public static Mappings blockStateMappings;
public static Mappings soundMappings;
public static Mappings statisticsMappings;
public class MappingData extends us.myles.ViaVersion.api.data.MappingData {
public static void init() {
Via.getPlatform().getLogger().info("Loading 1.14.4 -> 1.15 mappings...");
JsonObject diffmapping = MappingDataLoader.loadData("mappingdiff-1.14to1.15.json");
JsonObject mapping1_14 = MappingDataLoader.loadData("mapping-1.14.json", true);
JsonObject mapping1_15 = MappingDataLoader.loadData("mapping-1.15.json", true);
public MappingData() {
super("1.14", "1.15", true);
}
oldToNewItems.defaultReturnValue(-1);
blockStateMappings = new Mappings(mapping1_14.getAsJsonObject("blockstates"), mapping1_15.getAsJsonObject("blockstates"), diffmapping.getAsJsonObject("blockstates"));
blockMappings = new Mappings(mapping1_14.getAsJsonObject("blocks"), mapping1_15.getAsJsonObject("blocks"));
MappingDataLoader.mapIdentifiers(oldToNewItems, mapping1_14.getAsJsonObject("items"), mapping1_15.getAsJsonObject("items"));
soundMappings = new Mappings(mapping1_14.getAsJsonArray("sounds"), mapping1_15.getAsJsonArray("sounds"), false);
statisticsMappings = new Mappings(mapping1_14.getAsJsonArray("statistics"), mapping1_15.getAsJsonArray("statistics"));
@Override
protected Mappings loadFromArray(JsonObject oldMappings, JsonObject newMappings, @Nullable JsonObject diffMappings, String key) {
if (!key.equals("sounds")) {
return super.loadFromArray(oldMappings, newMappings, diffMappings, key);
}
// Ignore removed sounds
return new Mappings(oldMappings.getAsJsonArray(key), newMappings.getAsJsonArray(key), false);
}
}
@@ -7,6 +7,7 @@ import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_14;
import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.api.type.types.Particle;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.packets.EntityPackets;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.packets.InventoryPackets;
@@ -27,7 +28,7 @@ public class MetadataRewriter1_15To1_14_4 extends MetadataRewriter {
} else if (metadata.getMetaType() == MetaType1_14.BlockID) {
// Convert to new block id
int data = (int) metadata.getValue();
metadata.setValue(Protocol1_15To1_14_4.getNewBlockStateId(data));
metadata.setValue(protocol.getMappingData().getNewBlockStateId(data));
}
if (type == null) return;
@@ -47,6 +48,8 @@ public class MetadataRewriter1_15To1_14_4 extends MetadataRewriter {
} else if (metadata.getId() > 18) {
metadata.setId(metadata.getId() - 1);
}
} else if (type == Entity1_15Types.EntityType.AREA_EFFECT_CLOUD && metadata.getId() == 10) {
rewriteParticle((Particle) metadata.getValue());
}
}
@@ -18,7 +18,7 @@ public class EntityPackets {
public static void register(Protocol1_15To1_14_4 protocol) {
MetadataRewriter1_15To1_14_4 metadataRewriter = protocol.get(MetadataRewriter1_15To1_14_4.class);
metadataRewriter.registerSpawnTrackerWithData(ClientboundPackets1_14.SPAWN_ENTITY, Entity1_15Types.EntityType.FALLING_BLOCK, Protocol1_15To1_14_4::getNewBlockStateId);
metadataRewriter.registerSpawnTrackerWithData(ClientboundPackets1_14.SPAWN_ENTITY, Entity1_15Types.EntityType.FALLING_BLOCK);
protocol.registerOutgoing(ClientboundPackets1_14.SPAWN_MOB, new PacketRemapper() {
@Override
@@ -1,21 +1,19 @@
package us.myles.ViaVersion.protocols.protocol1_15to1_14_4.packets;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.rewriters.ItemRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.ClientboundPackets1_14;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.ServerboundPackets1_14;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.RecipeRewriter1_14;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.Protocol1_15To1_14_4;
public class InventoryPackets {
public static void register(Protocol protocol) {
public static void register(Protocol1_15To1_14_4 protocol) {
ItemRewriter itemRewriter = new ItemRewriter(protocol, InventoryPackets::toClient, InventoryPackets::toServer);
itemRewriter.registerSetCooldown(ClientboundPackets1_14.COOLDOWN, InventoryPackets::getNewItemId);
itemRewriter.registerSetCooldown(ClientboundPackets1_14.COOLDOWN);
itemRewriter.registerWindowItems(ClientboundPackets1_14.WINDOW_ITEMS, Type.FLAT_VAR_INT_ITEM_ARRAY);
itemRewriter.registerTradeList(ClientboundPackets1_14.TRADE_LIST, Type.FLAT_VAR_INT_ITEM);
itemRewriter.registerSetSlot(ClientboundPackets1_14.SET_SLOT, Type.FLAT_VAR_INT_ITEM);
@@ -30,25 +28,11 @@ public class InventoryPackets {
public static void toClient(Item item) {
if (item == null) return;
item.setIdentifier(getNewItemId(item.getIdentifier()));
item.setIdentifier(Protocol1_15To1_14_4.MAPPINGS.getNewItemId(item.getIdentifier()));
}
public static void toServer(Item item) {
if (item == null) return;
item.setIdentifier(getOldItemId(item.getIdentifier()));
}
public static int getNewItemId(int id) {
int newId = MappingData.oldToNewItems.get(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.15 item for 1.14 item " + id);
return 1;
}
return newId;
}
public static int getOldItemId(int id) {
int oldId = MappingData.oldToNewItems.inverse().get(id);
return oldId != -1 ? oldId : 1;
item.setIdentifier(Protocol1_15To1_14_4.MAPPINGS.getOldItemId(item.getIdentifier()));
}
}
@@ -3,7 +3,6 @@ package us.myles.ViaVersion.protocols.protocol1_15to1_14_4.packets;
import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.BlockRewriter;
@@ -15,8 +14,8 @@ import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.types.Chunk1_15Type;
public class WorldPackets {
public static void register(Protocol protocol) {
BlockRewriter blockRewriter = new BlockRewriter(protocol, Type.POSITION1_14, Protocol1_15To1_14_4::getNewBlockStateId, Protocol1_15To1_14_4::getNewBlockId);
public static void register(Protocol1_15To1_14_4 protocol) {
BlockRewriter blockRewriter = new BlockRewriter(protocol, Type.POSITION1_14);
blockRewriter.registerBlockAction(ClientboundPackets1_14.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_14.BLOCK_CHANGE);
@@ -59,7 +58,7 @@ public class WorldPackets {
if (section == null) continue;
for (int i = 0; i < section.getPaletteSize(); i++) {
int old = section.getPaletteEntry(i);
int newId = Protocol1_15To1_14_4.getNewBlockStateId(old);
int newId = protocol.getMappingData().getNewBlockStateId(old);
section.setPaletteEntry(i, newId);
}
}
@@ -68,7 +67,7 @@ public class WorldPackets {
}
});
blockRewriter.registerEffect(ClientboundPackets1_14.EFFECT, 1010, 2001, InventoryPackets::getNewItemId);
blockRewriter.registerEffect(ClientboundPackets1_14.EFFECT, 1010, 2001);
protocol.registerOutgoing(ClientboundPackets1_14.SPAWN_PARTICLE, new PacketRemapper() {
@Override
public void registerMap() {
@@ -88,7 +87,7 @@ public class WorldPackets {
int id = wrapper.get(Type.INT, 0);
if (id == 3 || id == 23) {
int data = wrapper.passthrough(Type.VAR_INT);
wrapper.set(Type.VAR_INT, 0, Protocol1_15To1_14_4.getNewBlockStateId(data));
wrapper.set(Type.VAR_INT, 0, protocol.getMappingData().getNewBlockStateId(data));
} else if (id == 32) {
InventoryPackets.toClient(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM));
}
@@ -1,9 +1,9 @@
package us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.api.rewriters.RegistryType;
import us.myles.ViaVersion.api.rewriters.SoundRewriter;
import us.myles.ViaVersion.api.rewriters.StatisticsRewriter;
@@ -20,27 +20,27 @@ import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.ServerboundPackets1_16
public class Protocol1_16_2To1_16_1 extends Protocol<ClientboundPackets1_16, ClientboundPackets1_16_2, ServerboundPackets1_16, ServerboundPackets1_16_2> {
public static final MappingData MAPPINGS = new MappingData();
private TagRewriter tagRewriter;
public Protocol1_16_2To1_16_1() {
super(ClientboundPackets1_16.class, ClientboundPackets1_16_2.class, ServerboundPackets1_16.class, ServerboundPackets1_16_2.class, true);
super(ClientboundPackets1_16.class, ClientboundPackets1_16_2.class, ServerboundPackets1_16.class, ServerboundPackets1_16_2.class);
}
@Override
protected void registerPackets() {
MetadataRewriter1_16_2To1_16_1 metadataRewriter = new MetadataRewriter1_16_2To1_16_1(this);
MetadataRewriter metadataRewriter = new MetadataRewriter1_16_2To1_16_1(this);
EntityPackets.register(this);
WorldPackets.register(this);
InventoryPackets.register(this);
tagRewriter = new TagRewriter(this, Protocol1_16_2To1_16_1::getNewBlockId, InventoryPackets::getNewItemId, metadataRewriter::getNewEntityId);
tagRewriter = new TagRewriter(this, metadataRewriter::getNewEntityId);
tagRewriter.register(ClientboundPackets1_16.TAGS);
new StatisticsRewriter(this, Protocol1_16_2To1_16_1::getNewBlockId, InventoryPackets::getNewItemId,
metadataRewriter::getNewEntityId).register(ClientboundPackets1_16.STATISTICS);
new StatisticsRewriter(this, metadataRewriter::getNewEntityId).register(ClientboundPackets1_16.STATISTICS);
SoundRewriter soundRewriter = new SoundRewriter(this, id -> MappingData.soundMappings.getNewId(id));
SoundRewriter soundRewriter = new SoundRewriter(this);
soundRewriter.registerSound(ClientboundPackets1_16.SOUND);
soundRewriter.registerSound(ClientboundPackets1_16.ENTITY_SOUND);
@@ -77,9 +77,7 @@ public class Protocol1_16_2To1_16_1 extends Protocol<ClientboundPackets1_16, Cli
}
@Override
protected void loadMappingData() {
MappingData.init();
protected void onMappingDataLoaded() {
tagRewriter.addTag(RegistryType.ITEM, "minecraft:stone_crafting_materials", 14, 962);
tagRewriter.addEmptyTag(RegistryType.BLOCK, "minecraft:mushroom_grow_block");
@@ -95,26 +93,13 @@ public class Protocol1_16_2To1_16_1 extends Protocol<ClientboundPackets1_16, Cli
"minecraft:base_stone_nether", "minecraft:base_stone_overworld");
}
public static int getNewBlockStateId(int id) {
int newId = MappingData.blockStateMappings.getNewId(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.16.2 blockstate for 1.16 blockstate " + id);
return 0;
}
return newId;
}
public static int getNewBlockId(int id) {
int newId = MappingData.blockMappings.getNewId(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.16.2 block for 1.16 block " + id);
return 0;
}
return newId;
}
@Override
public void init(UserConnection userConnection) {
userConnection.put(new EntityTracker1_16_2(userConnection));
}
@Override
public MappingData getMappingData() {
return MAPPINGS;
}
}
@@ -7,28 +7,22 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
import com.google.gson.JsonObject;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
import us.myles.ViaVersion.api.data.Mappings;
import us.myles.ViaVersion.api.minecraft.nbt.BinaryTagIO;
import us.myles.ViaVersion.util.Int2IntBiMap;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class MappingData {
public static CompoundTag dimensionRegistry;
public static Map<String, CompoundTag> dimensionDataMap = new HashMap<>();
public static Int2IntBiMap oldToNewItems = new Int2IntBiMap();
public static Mappings blockMappings;
public static Mappings blockStateMappings;
public static Mappings soundMappings;
public class MappingData extends us.myles.ViaVersion.api.data.MappingData {
private final Map<String, CompoundTag> dimensionDataMap = new HashMap<>();
private CompoundTag dimensionRegistry;
public static void init() {
Via.getPlatform().getLogger().info("Loading 1.16.1 -> 1.16.2 mappings...");
JsonObject diffmapping = MappingDataLoader.loadData("mappingdiff-1.16.1to1.16.2.json");
JsonObject mapping1_16 = MappingDataLoader.loadData("mapping-1.16.json", true);
JsonObject mapping1_16_2 = MappingDataLoader.loadData("mapping-1.16.2.json", true);
public MappingData() {
super("1.16", "1.16.2", true);
}
@Override
public void loadExtras(JsonObject oldMappings, JsonObject newMappings, JsonObject diffMappings) {
try {
dimensionRegistry = BinaryTagIO.readCompressedInputStream(MappingDataLoader.getResource("dimension-registry-1.16.2.nbt"));
} catch (IOException e) {
@@ -36,12 +30,6 @@ public class MappingData {
e.printStackTrace();
}
oldToNewItems.defaultReturnValue(-1);
blockStateMappings = new Mappings(mapping1_16.getAsJsonObject("blockstates"), mapping1_16_2.getAsJsonObject("blockstates"), diffmapping.getAsJsonObject("blockstates"));
blockMappings = new Mappings(mapping1_16.getAsJsonObject("blocks"), mapping1_16_2.getAsJsonObject("blocks"));
MappingDataLoader.mapIdentifiers(oldToNewItems, mapping1_16.getAsJsonObject("items"), mapping1_16_2.getAsJsonObject("items"));
soundMappings = new Mappings(mapping1_16.getAsJsonArray("sounds"), mapping1_16_2.getAsJsonArray("sounds"));
// Data of each dimension
ListTag dimensions = ((CompoundTag) dimensionRegistry.get("minecraft:dimension_type")).get("value");
for (Tag dimension : dimensions) {
@@ -51,4 +39,12 @@ public class MappingData {
dimensionDataMap.put(((StringTag) dimensionCompound.get("name")).getValue(), dimensionData);
}
}
public Map<String, CompoundTag> getDimensionDataMap() {
return dimensionDataMap;
}
public CompoundTag getDimensionRegistry() {
return dimensionRegistry;
}
}
@@ -8,6 +8,7 @@ import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.minecraft.metadata.Metadata;
import us.myles.ViaVersion.api.minecraft.metadata.types.MetaType1_14;
import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.api.type.types.Particle;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.Protocol1_16_2To1_16_1;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.packets.InventoryPackets;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.storage.EntityTracker1_16_2;
@@ -27,7 +28,7 @@ public class MetadataRewriter1_16_2To1_16_1 extends MetadataRewriter {
InventoryPackets.toClient((Item) metadata.getValue());
} else if (metadata.getMetaType() == MetaType1_14.BlockID) {
int data = (int) metadata.getValue();
metadata.setValue(Protocol1_16_2To1_16_1.getNewBlockStateId(data));
metadata.setValue(protocol.getMappingData().getNewBlockStateId(data));
}
if (type == null) return;
@@ -38,6 +39,10 @@ public class MetadataRewriter1_16_2To1_16_1 extends MetadataRewriter {
} else if (metadata.getId() == 16) {
metadata.setId(15);
}
} else if (type.is(Entity1_16_2Types.EntityType.AREA_EFFECT_CLOUD)) {
if (metadata.getId() == 10) {
rewriteParticle((Particle) metadata.getValue());
}
}
}
@@ -7,7 +7,6 @@ import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.version.Types1_14;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.Protocol1_16_2To1_16_1;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.metadata.MetadataRewriter1_16_2To1_16_1;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.storage.EntityTracker1_16_2;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.ClientboundPackets1_16;
@@ -16,8 +15,7 @@ public class EntityPackets {
public static void register(Protocol1_16_2To1_16_1 protocol) {
MetadataRewriter1_16_2To1_16_1 metadataRewriter = protocol.get(MetadataRewriter1_16_2To1_16_1.class);
metadataRewriter.registerSpawnTrackerWithData(ClientboundPackets1_16.SPAWN_ENTITY, Entity1_16_2Types.EntityType.FALLING_BLOCK, Protocol1_16_2To1_16_1::getNewBlockStateId);
metadataRewriter.registerSpawnTrackerWithData(ClientboundPackets1_16.SPAWN_ENTITY, Entity1_16_2Types.EntityType.FALLING_BLOCK);
metadataRewriter.registerTracker(ClientboundPackets1_16.SPAWN_MOB);
metadataRewriter.registerTracker(ClientboundPackets1_16.SPAWN_PLAYER, Entity1_16_2Types.EntityType.PLAYER);
metadataRewriter.registerMetadataRewriter(ClientboundPackets1_16.ENTITY_METADATA, Types1_14.METADATA_LIST);
@@ -39,7 +37,7 @@ public class EntityPackets {
handler(wrapper -> {
// Throw away the old dimension registry, extra conversion would be too hard of a hit
wrapper.read(Type.NBT);
wrapper.write(Type.NBT, MappingData.dimensionRegistry);
wrapper.write(Type.NBT, protocol.getMappingData().getDimensionRegistry());
// Instead of the dimension's resource key, it now just wants the data directly
String dimensionType = wrapper.read(Type.STRING);
@@ -67,7 +65,7 @@ public class EntityPackets {
}
public static CompoundTag getDimensionData(String dimensionType) {
CompoundTag tag = MappingData.dimensionDataMap.get(dimensionType);
CompoundTag tag = Protocol1_16_2To1_16_1.MAPPINGS.getDimensionDataMap().get(dimensionType);
if (tag == null) {
Via.getPlatform().getLogger().severe("Could not get dimension data of " + dimensionType);
throw new NullPointerException("Dimension data for " + dimensionType + " is null!");
@@ -1,13 +1,11 @@
package us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.packets;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.ItemRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.Protocol1_16_2To1_16_1;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.ServerboundPackets1_16_2;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.ClientboundPackets1_16;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.data.RecipeRewriter1_16;
@@ -16,7 +14,7 @@ public class InventoryPackets {
public static void register(Protocol1_16_2To1_16_1 protocol) {
ItemRewriter itemRewriter = new ItemRewriter(protocol, InventoryPackets::toClient, InventoryPackets::toServer);
itemRewriter.registerSetCooldown(ClientboundPackets1_16.COOLDOWN, InventoryPackets::getNewItemId);
itemRewriter.registerSetCooldown(ClientboundPackets1_16.COOLDOWN);
itemRewriter.registerWindowItems(ClientboundPackets1_16.WINDOW_ITEMS, Type.FLAT_VAR_INT_ITEM_ARRAY);
itemRewriter.registerTradeList(ClientboundPackets1_16.TRADE_LIST, Type.FLAT_VAR_INT_ITEM);
itemRewriter.registerSetSlot(ClientboundPackets1_16.SET_SLOT, Type.FLAT_VAR_INT_ITEM);
@@ -51,29 +49,17 @@ public class InventoryPackets {
handler(wrapper -> InventoryPackets.toServer(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)));
}
});
itemRewriter.registerSpawnParticle(ClientboundPackets1_16.SPAWN_PARTICLE, Type.FLAT_VAR_INT_ITEM, Type.DOUBLE);
}
public static void toClient(Item item) {
if (item == null) return;
item.setIdentifier(getNewItemId(item.getIdentifier()));
item.setIdentifier(Protocol1_16_2To1_16_1.MAPPINGS.getNewItemId(item.getIdentifier()));
}
public static void toServer(Item item) {
if (item == null) return;
item.setIdentifier(getOldItemId(item.getIdentifier()));
}
public static int getNewItemId(int id) {
int newId = MappingData.oldToNewItems.get(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.16.2 item for 1.16 item " + id);
return 1;
}
return newId;
}
public static int getOldItemId(int id) {
int oldId = MappingData.oldToNewItems.inverse().get(id);
return oldId != -1 ? oldId : 1;
item.setIdentifier(Protocol1_16_2To1_16_1.MAPPINGS.getOldItemId(item.getIdentifier()));
}
}
@@ -23,7 +23,7 @@ public class WorldPackets {
private static final BlockChangeRecord[] EMPTY_RECORDS = new BlockChangeRecord[0];
public static void register(Protocol protocol) {
BlockRewriter blockRewriter = new BlockRewriter(protocol, Type.POSITION1_14, Protocol1_16_2To1_16_1::getNewBlockStateId, Protocol1_16_2To1_16_1::getNewBlockId);
BlockRewriter blockRewriter = new BlockRewriter(protocol, Type.POSITION1_14);
blockRewriter.registerBlockAction(ClientboundPackets1_16.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_16.BLOCK_CHANGE);
@@ -41,7 +41,7 @@ public class WorldPackets {
if (section == null) continue;
for (int i = 0; i < section.getPaletteSize(); i++) {
int old = section.getPaletteEntry(i);
section.setPaletteEntry(i, Protocol1_16_2To1_16_1.getNewBlockStateId(old));
section.setPaletteEntry(i, protocol.getMappingData().getNewBlockStateId(old));
}
}
});
@@ -71,7 +71,7 @@ public class WorldPackets {
}
// Absolute y -> relative chunk section y
int blockId = Protocol1_16_2To1_16_1.getNewBlockStateId(record.getBlockId());
int blockId = protocol.getMappingData().getNewBlockStateId(record.getBlockId());
list.add(new BlockChangeRecord1_16_2(record.getSectionX(), record.getSectionY(), record.getSectionZ(), blockId));
}
@@ -84,14 +84,12 @@ public class WorldPackets {
newPacket.write(Type.LONG, chunkPosition | (chunkY & 0xFFFFFL));
newPacket.write(Type.BOOLEAN, false); // Ignore light updates
newPacket.write(Type.VAR_LONG_BLOCK_CHANGE_RECORD_ARRAY, sectionRecord.toArray(EMPTY_RECORDS));
newPacket.send(Protocol1_16_2To1_16_1.class);
newPacket.send(Protocol1_16_2To1_16_1.class, true, true);
}
});
}
});
blockRewriter.registerEffect(ClientboundPackets1_16.EFFECT, 1010, 2001, InventoryPackets::getNewItemId);
blockRewriter.registerSpawnParticle(ClientboundPackets1_16.SPAWN_PARTICLE, 3, 23, 34,
null, InventoryPackets::toClient, Type.FLAT_VAR_INT_ITEM, Type.DOUBLE);
blockRewriter.registerEffect(ClientboundPackets1_16.EFFECT, 1010, 2001);
}
}
@@ -0,0 +1,29 @@
package us.myles.ViaVersion.protocols.protocol1_16_4to1_16_3;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.ClientboundPackets1_16_2;
import us.myles.ViaVersion.protocols.protocol1_16_2to1_16_1.ServerboundPackets1_16_2;
public class Protocol1_16_4To1_16_3 extends Protocol<ClientboundPackets1_16_2, ClientboundPackets1_16_2, ServerboundPackets1_16_2, ServerboundPackets1_16_2> {
public Protocol1_16_4To1_16_3() {
super(ClientboundPackets1_16_2.class, ClientboundPackets1_16_2.class, ServerboundPackets1_16_2.class, ServerboundPackets1_16_2.class);
}
@Override
protected void registerPackets() {
registerIncoming(ServerboundPackets1_16_2.EDIT_BOOK, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.FLAT_VAR_INT_ITEM);
map(Type.BOOLEAN);
handler(wrapper -> {
int slot = wrapper.read(Type.VAR_INT);
wrapper.write(Type.VAR_INT, slot == 40 ? 1 : 0); // 40 = offhand, everything else assumed as mainhand
});
}
});
}
}
@@ -9,6 +9,7 @@ import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.ComponentRewriter;
import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.api.rewriters.RegistryType;
import us.myles.ViaVersion.api.rewriters.SoundRewriter;
import us.myles.ViaVersion.api.rewriters.StatisticsRewriter;
@@ -35,25 +36,25 @@ import java.util.UUID;
public class Protocol1_16To1_15_2 extends Protocol<ClientboundPackets1_15, ClientboundPackets1_16, ServerboundPackets1_14, ServerboundPackets1_16> {
private static final UUID ZERO_UUID = new UUID(0, 0);
public static final MappingData MAPPINGS = new MappingData();
private TagRewriter tagRewriter;
public Protocol1_16To1_15_2() {
super(ClientboundPackets1_15.class, ClientboundPackets1_16.class, ServerboundPackets1_14.class, ServerboundPackets1_16.class, true);
super(ClientboundPackets1_15.class, ClientboundPackets1_16.class, ServerboundPackets1_14.class, ServerboundPackets1_16.class);
}
@Override
protected void registerPackets() {
MetadataRewriter1_16To1_15_2 metadataRewriter = new MetadataRewriter1_16To1_15_2(this);
MetadataRewriter metadataRewriter = new MetadataRewriter1_16To1_15_2(this);
EntityPackets.register(this);
WorldPackets.register(this);
InventoryPackets.register(this);
tagRewriter = new TagRewriter(this, Protocol1_16To1_15_2::getNewBlockId, InventoryPackets::getNewItemId, metadataRewriter::getNewEntityId);
tagRewriter = new TagRewriter(this, metadataRewriter::getNewEntityId);
tagRewriter.register(ClientboundPackets1_15.TAGS);
new StatisticsRewriter(this, Protocol1_16To1_15_2::getNewBlockId, InventoryPackets::getNewItemId,
metadataRewriter::getNewEntityId, id -> MappingData.statisticsMappings.getNewId(id)).register(ClientboundPackets1_15.STATISTICS);
new StatisticsRewriter(this, metadataRewriter::getNewEntityId).register(ClientboundPackets1_15.STATISTICS);
// Login Success
registerOutgoing(State.LOGIN, 0x02, 0x02, new PacketRemapper() {
@@ -124,7 +125,7 @@ public class Protocol1_16To1_15_2 extends Protocol<ClientboundPackets1_15, Clien
componentRewriter.registerTitle(ClientboundPackets1_15.TITLE);
componentRewriter.registerCombatEvent(ClientboundPackets1_15.COMBAT_EVENT);
SoundRewriter soundRewriter = new SoundRewriter(this, id -> MappingData.soundMappings.getNewId(id));
SoundRewriter soundRewriter = new SoundRewriter(this);
soundRewriter.registerSound(ClientboundPackets1_15.SOUND);
soundRewriter.registerSound(ClientboundPackets1_15.ENTITY_SOUND);
@@ -206,9 +207,7 @@ public class Protocol1_16To1_15_2 extends Protocol<ClientboundPackets1_15, Clien
}
@Override
protected void loadMappingData() {
MappingData.init();
protected void onMappingDataLoaded() {
int[] wallPostOverrideTag = new int[47];
int arrayIndex = 0;
wallPostOverrideTag[arrayIndex++] = 140;
@@ -253,27 +252,14 @@ public class Protocol1_16To1_15_2 extends Protocol<ClientboundPackets1_15, Clien
"minecraft:lectern_books", "minecraft:music_discs", "minecraft:small_flowers", "minecraft:tall_flowers", "minecraft:trapdoors", "minecraft:walls", "minecraft:wooden_fences");
}
public static int getNewBlockStateId(int id) {
int newId = MappingData.blockStateMappings.getNewId(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.16 blockstate for 1.15.2 blockstate " + id);
return 0;
}
return newId;
}
public static int getNewBlockId(int id) {
int newId = MappingData.blockMappings.getNewId(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.16 block for 1.15.2 block " + id);
return 0;
}
return newId;
}
@Override
public void init(UserConnection userConnection) {
userConnection.put(new EntityTracker1_16(userConnection));
userConnection.put(new InventoryTracker1_16(userConnection));
}
@Override
public MappingData getMappingData() {
return MAPPINGS;
}
}
@@ -3,32 +3,16 @@ package us.myles.ViaVersion.protocols.protocol1_16to1_15_2.data;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.gson.JsonObject;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.MappingDataLoader;
import us.myles.ViaVersion.api.data.Mappings;
import us.myles.ViaVersion.util.Int2IntBiMap;
public class MappingData {
public static Int2IntBiMap oldToNewItems = new Int2IntBiMap();
public static BiMap<String, String> attributeMappings = HashBiMap.create();
public static Mappings blockMappings;
public static Mappings blockStateMappings;
public static Mappings soundMappings;
public static Mappings statisticsMappings;
public class MappingData extends us.myles.ViaVersion.api.data.MappingData {
private final BiMap<String, String> attributeMappings = HashBiMap.create();
public static void init() {
Via.getPlatform().getLogger().info("Loading 1.15 -> 1.16 mappings...");
JsonObject diffmapping = MappingDataLoader.loadData("mappingdiff-1.15to1.16.json");
JsonObject mapping1_15 = MappingDataLoader.loadData("mapping-1.15.json", true);
JsonObject mapping1_16 = MappingDataLoader.loadData("mapping-1.16.json", true);
oldToNewItems.defaultReturnValue(-1);
blockStateMappings = new Mappings(mapping1_15.getAsJsonObject("blockstates"), mapping1_16.getAsJsonObject("blockstates"), diffmapping.getAsJsonObject("blockstates"));
blockMappings = new Mappings(mapping1_15.getAsJsonObject("blocks"), mapping1_16.getAsJsonObject("blocks"));
MappingDataLoader.mapIdentifiers(oldToNewItems, mapping1_15.getAsJsonObject("items"), mapping1_16.getAsJsonObject("items"), diffmapping.getAsJsonObject("items"));
soundMappings = new Mappings(mapping1_15.getAsJsonArray("sounds"), mapping1_16.getAsJsonArray("sounds"), diffmapping.getAsJsonObject("sounds"));
statisticsMappings = new Mappings(mapping1_15.getAsJsonArray("statistics"), mapping1_16.getAsJsonArray("statistics"));
public MappingData() {
super("1.15", "1.16", true);
}
@Override
protected void loadExtras(JsonObject oldMappings, JsonObject newMappings, JsonObject diffMappings) {
attributeMappings.put("generic.maxHealth", "minecraft:generic.max_health");
attributeMappings.put("zombie.spawnReinforcements", "minecraft:zombie.spawn_reinforcements");
attributeMappings.put("horse.jumpStrength", "minecraft:horse.jump_strength");
@@ -41,4 +25,8 @@ public class MappingData {
attributeMappings.put("generic.attackSpeed", "minecraft:generic.attack_speed");
attributeMappings.put("generic.armorToughness", "minecraft:generic.armor_toughness");
}
public BiMap<String, String> getAttributeMappings() {
return attributeMappings;
}
}
@@ -11,7 +11,6 @@ import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.api.type.types.Particle;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.Protocol1_16To1_15_2;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.packets.InventoryPackets;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.packets.WorldPackets;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.storage.EntityTracker1_16;
import java.util.List;
@@ -30,15 +29,14 @@ public class MetadataRewriter1_16To1_15_2 extends MetadataRewriter {
InventoryPackets.toClient((Item) metadata.getValue());
} else if (metadata.getMetaType() == MetaType1_14.BlockID) {
int data = (int) metadata.getValue();
metadata.setValue(Protocol1_16To1_15_2.getNewBlockStateId(data));
metadata.setValue(protocol.getMappingData().getNewBlockStateId(data));
}
if (type == null) return;
if (type == Entity1_16Types.EntityType.AREA_EFFECT_CLOUD) {
if (metadata.getId() == 10) {
Particle particle = (Particle) metadata.getValue();
particle.setId(WorldPackets.getNewParticleId(particle.getId()));
rewriteParticle((Particle) metadata.getValue());
}
} else if (type.isOrHasParent(Entity1_16Types.EntityType.ABSTRACT_ARROW)) {
if (metadata.getId() == 8) {
@@ -17,7 +17,6 @@ import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.ClientboundPackets1_15
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.ClientboundPackets1_16;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.Protocol1_16To1_15_2;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.ServerboundPackets1_16;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.metadata.MetadataRewriter1_16To1_15_2;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.storage.EntityTracker1_16;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.storage.InventoryTracker1_16;
@@ -156,7 +155,7 @@ public class EntityPackets {
}
});
metadataRewriter.registerSpawnTrackerWithData(ClientboundPackets1_15.SPAWN_ENTITY, Entity1_16Types.EntityType.FALLING_BLOCK, Protocol1_16To1_15_2::getNewBlockStateId);
metadataRewriter.registerSpawnTrackerWithData(ClientboundPackets1_15.SPAWN_ENTITY, Entity1_16Types.EntityType.FALLING_BLOCK);
metadataRewriter.registerTracker(ClientboundPackets1_15.SPAWN_MOB);
metadataRewriter.registerTracker(ClientboundPackets1_15.SPAWN_PLAYER, Entity1_16Types.EntityType.PLAYER);
metadataRewriter.registerMetadataRewriter(ClientboundPackets1_15.ENTITY_METADATA, Types1_14.METADATA_LIST);
@@ -212,14 +211,18 @@ public class EntityPackets {
handler(wrapper -> {
wrapper.passthrough(Type.VAR_INT);
int size = wrapper.passthrough(Type.INT);
int actualSize = size;
for (int i = 0; i < size; i++) {
// Attributes have been renamed and are now namespaced identifiers
String key = wrapper.read(Type.STRING);
String attributeIdentifier = MappingData.attributeMappings.get(key);
String attributeIdentifier = protocol.getMappingData().getAttributeMappings().get(key);
if (attributeIdentifier == null) {
attributeIdentifier = "minecraft:" + key;
if (!us.myles.ViaVersion.protocols.protocol1_13to1_12_2.data.MappingData.isValid1_13Channel(attributeIdentifier)) {
Via.getPlatform().getLogger().warning("Invalid attribute: " + key);
if (!Via.getConfig().isSuppressConversionWarnings()) {
Via.getPlatform().getLogger().warning("Invalid attribute: " + key);
}
actualSize--;
wrapper.read(Type.DOUBLE);
int modifierSize = wrapper.read(Type.VAR_INT);
for (int j = 0; j < modifierSize; j++) {
@@ -241,6 +244,9 @@ public class EntityPackets {
wrapper.passthrough(Type.BYTE);
}
}
if (size != actualSize) {
wrapper.set(Type.INT, 0, actualSize);
}
});
}
});
@@ -6,24 +6,22 @@ import com.github.steveice10.opennbt.tag.builtin.ListTag;
import com.github.steveice10.opennbt.tag.builtin.LongTag;
import com.github.steveice10.opennbt.tag.builtin.StringTag;
import com.github.steveice10.opennbt.tag.builtin.Tag;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.minecraft.item.Item;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.ItemRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.api.type.types.UUIDIntArrayType;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.ClientboundPackets1_15;
import us.myles.ViaVersion.protocols.protocol1_14to1_13_2.data.RecipeRewriter1_14;
import us.myles.ViaVersion.protocols.protocol1_15to1_14_4.ClientboundPackets1_15;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.Protocol1_16To1_15_2;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.ServerboundPackets1_16;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.data.MappingData;
import us.myles.ViaVersion.protocols.protocol1_16to1_15_2.storage.InventoryTracker1_16;
import java.util.UUID;
public class InventoryPackets {
public static void register(Protocol protocol) {
public static void register(Protocol1_16To1_15_2 protocol) {
ItemRewriter itemRewriter = new ItemRewriter(protocol, InventoryPackets::toClient, InventoryPackets::toServer);
protocol.registerOutgoing(ClientboundPackets1_15.OPEN_WINDOW, new PacketRemapper() {
@@ -76,7 +74,7 @@ public class InventoryPackets {
}
});
itemRewriter.registerSetCooldown(ClientboundPackets1_15.COOLDOWN, InventoryPackets::getNewItemId);
itemRewriter.registerSetCooldown(ClientboundPackets1_15.COOLDOWN);
itemRewriter.registerWindowItems(ClientboundPackets1_15.WINDOW_ITEMS, Type.FLAT_VAR_INT_ITEM_ARRAY);
itemRewriter.registerTradeList(ClientboundPackets1_15.TRADE_LIST, Type.FLAT_VAR_INT_ITEM);
itemRewriter.registerSetSlot(ClientboundPackets1_15.SET_SLOT, Type.FLAT_VAR_INT_ITEM);
@@ -118,6 +116,8 @@ public class InventoryPackets {
handler(wrapper -> InventoryPackets.toServer(wrapper.passthrough(Type.FLAT_VAR_INT_ITEM)));
}
});
itemRewriter.registerSpawnParticle(ClientboundPackets1_15.SPAWN_PARTICLE, Type.FLAT_VAR_INT_ITEM, Type.DOUBLE);
}
public static void toClient(Item item) {
@@ -137,13 +137,13 @@ public class InventoryPackets {
}
oldToNewAttributes(item);
item.setIdentifier(getNewItemId(item.getIdentifier()));
item.setIdentifier(Protocol1_16To1_15_2.MAPPINGS.getNewItemId(item.getIdentifier()));
}
public static void toServer(Item item) {
if (item == null) return;
item.setIdentifier(getOldItemId(item.getIdentifier()));
item.setIdentifier(Protocol1_16To1_15_2.MAPPINGS.getOldItemId(item.getIdentifier()));
if (item.getIdentifier() == 771 && item.getTag() != null) {
CompoundTag tag = item.getTag();
@@ -200,7 +200,7 @@ public class InventoryPackets {
}
public static void rewriteAttributeName(CompoundTag compoundTag, String entryName, boolean inverse) {
StringTag attributeNameTag = compoundTag.get("AttributeName");
StringTag attributeNameTag = compoundTag.get(entryName);
if (attributeNameTag == null) return;
String attributeName = attributeNameTag.getValue();
@@ -208,23 +208,10 @@ public class InventoryPackets {
attributeName = "minecraft:" + attributeName;
}
String mappedAttribute = (inverse ? MappingData.attributeMappings.inverse() : MappingData.attributeMappings).get(attributeName);
String mappedAttribute = (inverse ? Protocol1_16To1_15_2.MAPPINGS.getAttributeMappings().inverse()
: Protocol1_16To1_15_2.MAPPINGS.getAttributeMappings()).get(attributeName);
if (mappedAttribute == null) return;
attributeNameTag.setValue(mappedAttribute);
}
public static int getNewItemId(int id) {
int newId = MappingData.oldToNewItems.get(id);
if (newId == -1) {
Via.getPlatform().getLogger().warning("Missing 1.16 item for 1.15.2 item " + id);
return 1;
}
return newId;
}
public static int getOldItemId(int id) {
int oldId = MappingData.oldToNewItems.inverse().get(id);
return oldId != -1 ? oldId : 1;
}
}
@@ -8,7 +8,6 @@ import com.github.steveice10.opennbt.tag.builtin.Tag;
import us.myles.ViaVersion.api.minecraft.Position;
import us.myles.ViaVersion.api.minecraft.chunks.Chunk;
import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.rewriters.BlockRewriter;
import us.myles.ViaVersion.api.type.Type;
@@ -23,8 +22,8 @@ import java.util.UUID;
public class WorldPackets {
public static void register(Protocol protocol) {
BlockRewriter blockRewriter = new BlockRewriter(protocol, Type.POSITION1_14, Protocol1_16To1_15_2::getNewBlockStateId, Protocol1_16To1_15_2::getNewBlockId);
public static void register(Protocol1_16To1_15_2 protocol) {
BlockRewriter blockRewriter = new BlockRewriter(protocol, Type.POSITION1_14);
blockRewriter.registerBlockAction(ClientboundPackets1_15.BLOCK_ACTION);
blockRewriter.registerBlockChange(ClientboundPackets1_15.BLOCK_CHANGE);
@@ -54,7 +53,7 @@ public class WorldPackets {
if (section == null) continue;
for (int i = 0; i < section.getPaletteSize(); i++) {
int old = section.getPaletteEntry(i);
section.setPaletteEntry(i, Protocol1_16To1_15_2.getNewBlockStateId(old));
section.setPaletteEntry(i, protocol.getMappingData().getNewBlockStateId(old));
}
}
@@ -86,9 +85,7 @@ public class WorldPackets {
}
});
blockRewriter.registerEffect(ClientboundPackets1_15.EFFECT, 1010, 2001, InventoryPackets::getNewItemId);
blockRewriter.registerSpawnParticle(ClientboundPackets1_15.SPAWN_PARTICLE, 3, 23, 32,
WorldPackets::getNewParticleId, InventoryPackets::toClient, Type.FLAT_VAR_INT_ITEM, Type.DOUBLE);
blockRewriter.registerEffect(ClientboundPackets1_15.EFFECT, 1010, 2001);
}
private static void handleBlockEntity(CompoundTag compoundTag) {
@@ -119,11 +116,4 @@ public class WorldPackets {
compoundTag.put(skullOwnerTag);
}
}
public static int getNewParticleId(int id) {
if (id >= 27) {
id += 2; // soul flame, soul
}
return id;
}
}
@@ -12,6 +12,7 @@ import us.myles.ViaVersion.api.minecraft.chunks.ChunkSection;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketHandler;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.remapper.ValueTransformer;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.chunks.FakeTileEntity;
import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld;
@@ -23,6 +24,13 @@ import java.util.List;
public class Protocol1_9_3To1_9_1_2 extends Protocol<ClientboundPackets1_9, ClientboundPackets1_9_3, ServerboundPackets1_9, ServerboundPackets1_9_3> {
public static final ValueTransformer<Short, Short> ADJUST_PITCH = new ValueTransformer<Short, Short>(Type.UNSIGNED_BYTE, Type.UNSIGNED_BYTE) {
@Override
public Short transform(PacketWrapper wrapper, Short inputValue) throws Exception {
return (short) Math.round(inputValue / 63.5F * 63.0F);
}
};
public Protocol1_9_3To1_9_1_2() {
super(ClientboundPackets1_9.class, ClientboundPackets1_9_3.class, ServerboundPackets1_9.class, ServerboundPackets1_9_3.class);
}
@@ -134,6 +142,20 @@ public class Protocol1_9_3To1_9_1_2 extends Protocol<ClientboundPackets1_9, Clie
});
}
});
// Sound effect
registerOutgoing(ClientboundPackets1_9.SOUND, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.VAR_INT); // 0 - Sound name
map(Type.VAR_INT); // 1 - Sound Category
map(Type.INT); // 2 - x
map(Type.INT); // 3 - y
map(Type.INT); // 4 - z
map(Type.FLOAT); // 5 - Volume
map(ADJUST_PITCH); // 6 - Pitch
}
});
}
@Override
@@ -10,6 +10,7 @@ import us.myles.ViaVersion.api.platform.providers.ViaProviders;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.remapper.PacketRemapper;
import us.myles.ViaVersion.api.remapper.ValueTransformer;
import us.myles.ViaVersion.api.rewriters.MetadataRewriter;
import us.myles.ViaVersion.api.type.Type;
import us.myles.ViaVersion.packets.State;
import us.myles.ViaVersion.protocols.protocol1_8.ClientboundPackets1_8;
@@ -94,13 +95,20 @@ public class Protocol1_9To1_8 extends Protocol<ClientboundPackets1_8, Clientboun
@Override
protected void registerPackets() {
new MetadataRewriter1_9To1_8(this);
MetadataRewriter metadataRewriter = new MetadataRewriter1_9To1_8(this);
// Disconnect workaround (JSON!)
registerOutgoing(State.LOGIN, 0x00, 0x00, new PacketRemapper() {
@Override
public void registerMap() {
map(Type.STRING, Protocol1_9To1_8.FIX_JSON); // 0 - Reason
handler(wrapper -> {
if (wrapper.isReadable(Type.COMPONENT, 0)) {
// Already written as json somewhere else
return;
}
wrapper.write(Type.COMPONENT, fixJson(wrapper.read(Type.STRING)));
});
}
});
Loaded 100 of 128 files, more files were not shown because too many files have changed in this diff. Show more