From a4794e3e483772ba195af3cad4d8c9f94b3e5672 Mon Sep 17 00:00:00 2001
From: RaphiMC <50594595+RaphiMC@users.noreply.github.com>
Date: Sun, 26 Nov 2023 21:11:41 +0100
Subject: [PATCH] Added and fixed tons of clientside fixes
---
build.gradle | 3 +
gradle.properties | 1 +
.../viafabricplus/ViaFabricPlus.java | 16 +-
.../fixes/ActionResultException.java | 41 +
.../fixes/ArmorUpdateListener.java | 67 +
.../fixes/ChestHandler1_13_2.java | 50 +
.../ClientPlayerInteractionManager1_18_2.java | 46 +-
.../viafabricplus/fixes/ClientsideFixes.java | 123 +-
.../fixes/EntityHeightOffsetsPre1_20_2.java | 199 ++-
.../fixes/EntityHitboxUpdateListener.java | 162 ++
.../fixes/PendingUpdateManager1_18_2.java | 62 +
.../fixes/TripleChestHandler1_13_2.java | 66 -
.../screen/ClassicItemSelectionScreen.java | 2 +-
.../fixes/diff/ItemRegistryDiff.java | 1373 +++++++++++++++++
.../fixes/diff/RecipesPre1_12.java | 106 --
.../fixes/diff/RenderableGlyphDiff.java | 982 ++++++++++++
.../fixes/recipe/AddBannerPatternRecipe.java | 183 +++
.../fixes/recipe/BannerPattern_1_13_2.java | 112 ++
.../fixes/recipe/RecipeInfo.java | 217 +++
.../fixes/recipe/Recipes1_11_2.java | 713 +++++++++
.../injection/access/IChunkTracker.java | 30 +
.../injection/access/IItemStack.java | 2 +-
.../injection/access/IMouseKeyboard.java | 28 +
.../injection/access/IRakSessionCodec.java | 28 +
.../injection/access/IScreenHandler.java | 5 +-
.../base/integration/MixinChunkTracker.java | 62 +
.../integration/MixinConnectScreen_1.java | 73 +-
.../mixin/base/integration/MixinDebugHud.java | 82 +-
.../MixinDownloadingTerrainScreen.java | 3 +
...ltiplayerServerListWidget_ServerEntry.java | 9 +-
.../integration/MixinRakSessionCodec.java | 50 +
.../fixes/authlib/MixinKeyPairResponse.java | 1 +
.../authlib/MixinYggdrasilUserApiService.java | 18 +-
....java => MixinAllowedAddressResolver.java} | 33 +-
...creenHandler.java => MixinBuiltChunk.java} | 21 +-
.../minecraft/MixinChatInputSuggestor.java | 95 ++
.../minecraft/MixinClientCommandSource.java | 49 +
.../MixinClientPlayerInteractionManager.java | 200 ---
.../fixes/minecraft/MixinClientWorld.java | 135 ++
.../minecraft/MixinEnchantmentHelper.java | 50 +
.../fixes/minecraft/MixinFlowableFluid.java | 55 +
.../fixes/minecraft/MixinFontStorage.java | 110 +-
.../fixes/minecraft/MixinGameOptions.java | 57 +
.../fixes/minecraft/MixinGameRenderer.java | 68 +
.../mixin/fixes/minecraft/MixinKeyboard.java | 60 +
.../fixes/minecraft/MixinMinecraftClient.java | 130 +-
.../mixin/fixes/minecraft/MixinMouse.java | 73 +
.../fixes/minecraft/MixinPlayerInventory.java | 62 +
...anager.java => MixinRedirectResolver.java} | 21 +-
.../fixes/minecraft/MixinServerAddress.java | 47 +
.../MixinServerResourcePackProvider.java | 28 +-
.../fixes/minecraft/MixinStringHelper.java | 9 +-
.../fixes/minecraft/MixinTextRenderer.java | 19 +-
.../minecraft/entity/MixinBoatEntity.java | 19 +
.../minecraft/entity/MixinLivingEntity.java | 9 +-
.../entity/MixinSkeletonHorseEntity.java | 19 +
.../minecraft/item/MixinDrawContext.java | 2 +-
.../item/MixinItemGroup_EntriesImpl.java | 13 +-
.../fixes/minecraft/item/MixinItemStack.java | 2 +-
.../network/MixinChatMessageC2SPacket.java | 13 +-
.../MixinClientCommonNetworkHandler.java | 46 +-
...ixinClientConfigurationNetworkHandler.java | 45 +
.../MixinClientLoginNetworkHandler.java | 38 +
.../MixinClientPlayNetworkHandler.java | 96 +-
.../MixinClientPlayerInteractionManager.java | 324 ++++
.../network/MixinCustomPayloadS2CPacket.java | 71 +
.../MixinMultiplayerServerListPinger.java | 41 +
.../minecraft/network/MixinPacketByteBuf.java | 37 +-
.../MixinUpdatePlayerAbilitiesC2SPacket.java | 22 +-
.../MixinAbstractCommandBlockScreen.java | 40 +
.../minecraft/screen/MixinBookEditScreen.java | 50 +
.../minecraft/screen/MixinChatScreen.java | 53 +-
.../screen/MixinCommandBlockScreen.java | 1 +
.../screen/MixinConnectScreen_1.java | 77 +-
.../screen/MixinCreativeInventoryScreen.java | 2 -
.../screen/MixinDownloadingTerrainScreen.java | 50 +-
.../screen/MixinGameModeSelectionScreen.java | 4 +-
...ModeSelectionScreen_GameModeSelection.java | 14 +-
.../screen/MixinJigsawBlockScreen.java | 4 +-
...reen.java => MixinMouseOptionsScreen.java} | 42 +-
.../fixes/minecraft/screen/MixinScreen.java | 4 +-
.../screen/MixinStructureBlockScreen_1.java | 5 +-
.../minecraft/screen/hud/MixinChatHud.java | 10 +-
.../minecraft/screen/hud/MixinInGameHud.java | 10 +-
.../screen/merchant/MixinMerchantScreen.java | 67 -
.../MixinAbstractFurnaceScreenHandler.java | 50 +
...xinBrewingStandScreenHandler_FuelSlot.java | 7 +-
.../MixinCraftingScreenHandler.java | 18 +-
.../MixinMerchantScreenHandler.java | 118 ++
.../MixinPlayerScreenHandler.java | 34 +-
.../screenhandler/MixinScreenHandler.java | 29 +-
.../viaversion/MixinCommandBlockProvider.java | 6 +-
.../viaversion/MixinEntityIdRewriter.java | 29 +-
.../viaversion/MixinEntityPackets1_19_4.java | 26 +
.../MixinInventoryAcknowledgements.java | 7 +-
.../viaversion/MixinInventoryPackets.java | 53 +-
.../viaversion/MixinInventoryPackets1_13.java | 29 +
.../viaversion/MixinInventoryPackets1_17.java | 51 +
...er.java => MixinInventoryTracker1_16.java} | 21 +-
.../viaversion/MixinNamedCompoundTagType.java | 37 +-
.../viaversion/MixinProtocol1_11To1_10.java | 2 +-
.../viaversion/MixinProtocol1_12To1_11_1.java | 16 +
.../mixin/fixes/viaversion/MixinTagType.java | 17 +
.../viaversion/MixinWorldPackets1_19.java | 8 +-
.../MixinAbstractFenceConnectionHandler.java | 6 +-
.../MixinGlassConnectionHandler.java | 6 +-
.../viaversion/MixinProtocolVersion.java | 9 +
.../reference/BuiltinEmptyGlyph1_12_2.java | 20 +-
.../protocolhack/ProtocolHack.java | 48 +-
.../impl/ViaFabricPlusVLLoader.java | 4 +-
.../netty/ViaFabricPlusViaDecoder.java | 13 +-
.../ViaFabricPlusAlphaInventoryProvider.java | 6 +-
.../ViaFabricPlusEncryptionProvider.java | 6 +-
... => ViaFabricPlusAckSequenceProvider.java} | 7 +-
.../ViaFabricPlusHandItemProvider.java | 10 +-
.../BlockStateTranslator.java | 51 +-
.../translator/ItemTranslator.java | 100 ++
.../translator/TextComponentTranslator.java | 56 +
.../protocolhack/util/ItemTranslator.java | 114 --
.../viafabricplus/save/impl/AccountsSave.java | 14 +
.../viafabricplus/save/impl/SettingsSave.java | 4 +-
.../screen/settings/ModeSettingRenderer.java | 2 +-
.../settings/base/AbstractSetting.java | 3 +-
.../settings/impl/DebugSettings.java | 9 +-
.../util/MouseSensitivityUtil.java | 34 +
.../assets/viafabricplus/lang/de_de.json | 1 +
.../assets/viafabricplus/lang/en_us.json | 3 +-
.../resources/viafabricplus.accesswidener | 11 +-
src/main/resources/viafabricplus.mixins.json | 61 +-
129 files changed, 7135 insertions(+), 1488 deletions(-)
create mode 100644 src/main/java/de/florianmichael/viafabricplus/fixes/ActionResultException.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/fixes/ArmorUpdateListener.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/fixes/ChestHandler1_13_2.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/fixes/EntityHitboxUpdateListener.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/fixes/PendingUpdateManager1_18_2.java
delete mode 100644 src/main/java/de/florianmichael/viafabricplus/fixes/TripleChestHandler1_13_2.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/fixes/diff/ItemRegistryDiff.java
delete mode 100644 src/main/java/de/florianmichael/viafabricplus/fixes/diff/RecipesPre1_12.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/fixes/diff/RenderableGlyphDiff.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/fixes/recipe/AddBannerPatternRecipe.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/fixes/recipe/BannerPattern_1_13_2.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/fixes/recipe/RecipeInfo.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/fixes/recipe/Recipes1_11_2.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/access/IChunkTracker.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/access/IMouseKeyboard.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/access/IRakSessionCodec.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinChunkTracker.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinRakSessionCodec.java
rename src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/{screen/MixinHandledScreens.java => MixinAllowedAddressResolver.java} (57%)
rename src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/{screen/merchant/MixinMerchantScreenHandler.java => MixinBuiltChunk.java} (75%)
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinChatInputSuggestor.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientCommandSource.java
delete mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientPlayerInteractionManager.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientWorld.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinEnchantmentHelper.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinFlowableFluid.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinGameOptions.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinGameRenderer.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinKeyboard.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinMouse.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinPlayerInventory.java
rename src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/{MixinPendingUpdateManager.java => MixinRedirectResolver.java} (62%)
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinServerAddress.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/network/MixinClientConfigurationNetworkHandler.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/network/MixinClientLoginNetworkHandler.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/network/MixinClientPlayerInteractionManager.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/network/MixinCustomPayloadS2CPacket.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/network/MixinMultiplayerServerListPinger.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/screen/MixinAbstractCommandBlockScreen.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/screen/MixinBookEditScreen.java
rename src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/screen/{MixinAnvilScreen.java => MixinMouseOptionsScreen.java} (52%)
delete mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/screen/merchant/MixinMerchantScreen.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/screen/screenhandler/MixinAbstractFurnaceScreenHandler.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/screen/screenhandler/MixinMerchantScreenHandler.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/MixinEntityPackets1_19_4.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/MixinInventoryPackets1_13.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/MixinInventoryPackets1_17.java
rename src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/{MixinSkullHandler.java => MixinInventoryTracker1_16.java} (60%)
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/MixinProtocol1_12To1_11_1.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/viaversion/MixinTagType.java
rename src/main/java/de/florianmichael/viafabricplus/protocolhack/provider/viaversion/{ViaFabricPlusMovementTransmitterProvider.java => ViaFabricPlusAckSequenceProvider.java} (80%)
rename src/main/java/de/florianmichael/viafabricplus/protocolhack/{util => translator}/BlockStateTranslator.java (52%)
create mode 100644 src/main/java/de/florianmichael/viafabricplus/protocolhack/translator/ItemTranslator.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/protocolhack/translator/TextComponentTranslator.java
delete mode 100644 src/main/java/de/florianmichael/viafabricplus/protocolhack/util/ItemTranslator.java
create mode 100644 src/main/java/de/florianmichael/viafabricplus/util/MouseSensitivityUtil.java
diff --git a/build.gradle b/build.gradle
index 687d216a2..574031e92 100644
--- a/build.gradle
+++ b/build.gradle
@@ -80,6 +80,9 @@ dependencies {
// Lenni0451 Libraries
jij "net.lenni0451:Reflect:${project.reflect_version}"
+ jij("net.lenni0451:MCPing:${project.mcping_version}") {
+ exclude group: "com.google.code.gson", module: "gson"
+ }
// Misc Libraries
jij("org.cloudburstmc.netty:netty-transport-raknet:${project.raknet_transport_version}") {
diff --git a/gradle.properties b/gradle.properties
index a91bbb4be..b9a99d4f3 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -27,6 +27,7 @@ raknet_transport_version=1.0.0.CR1-SNAPSHOT
# Lenni0451 Libraries
reflect_version=1.3.0
+mcping_version=1.3.0
# Misc Libraries
mod_menu_version=8.0.0
diff --git a/src/main/java/de/florianmichael/viafabricplus/ViaFabricPlus.java b/src/main/java/de/florianmichael/viafabricplus/ViaFabricPlus.java
index 21634897f..ebf6f1fe8 100644
--- a/src/main/java/de/florianmichael/viafabricplus/ViaFabricPlus.java
+++ b/src/main/java/de/florianmichael/viafabricplus/ViaFabricPlus.java
@@ -20,12 +20,11 @@
package de.florianmichael.viafabricplus;
import de.florianmichael.viafabricplus.event.PostGameLoadCallback;
-import de.florianmichael.viafabricplus.event.LoadCallback;
import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
-import de.florianmichael.viafabricplus.util.ClassLoaderPriorityUtil;
import de.florianmichael.viafabricplus.save.SaveManager;
import de.florianmichael.viafabricplus.settings.SettingsManager;
+import de.florianmichael.viafabricplus.util.ClassLoaderPriorityUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -38,7 +37,7 @@
* - Window interactions in <= 1.16.5 has changed and can be detected by the server
* - Most CTS protocol features aren't supported (see https://github.com/ViaVersion/ViaFabricPlus/issues/181)
* - Most CPE features aren't implemented correctly (see https://github.com/ViaVersion/ViaFabricPlus/issues/152)
- * - Bedrock scaffolding should be added as soon as ViaBedrock supports block placement (see https://github.com/ViaVersion/ViaFabricPlus/issues/204)
+ * - Check if MixinPlayerScreenHandler.injectTransferSlot is needed? Check git log
*
* TODO | Movement
* - X/Z Face based jump movement in <= 1.13.2 is broken (https://github.com/ViaVersion/ViaFabricPlus/issues/189)
@@ -46,13 +45,16 @@
* - Blit-jump is not supported in <= 1.8.9 (https://github.com/ViaVersion/ViaFabricPlus/issues/225)
*
* TODO | Migration v3
- * - Rename all methods
* - Use ViaProxy config patch for some clientside fixes options (Remove ViaFabricPlusVLViaConfig and MixinViaLegacyConfig)
- * - Fix auto detect to not be a huge mess
+ * - Add setting for VFP AlphaInventoryProvider
* - Fix MixinAbstractDonkeyEntity
- * - Boats are probably broken. Check entity height offset fix
* - Check TO DO in MixinEntity
- * - Diff ItemRegistryDiff from projects and add missing items
+ * - Fix MixinMultiplayerServerListWidget_ServerEntry
+ * - Test villagers
+ * - Test offhand
+ * - Check if attack cooldown is there or not
+ * - Test very large 1.8 chests
+ * - Test block ack
*/
public class ViaFabricPlus {
private static final ViaFabricPlus instance = new ViaFabricPlus();
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/ActionResultException.java b/src/main/java/de/florianmichael/viafabricplus/fixes/ActionResultException.java
new file mode 100644
index 000000000..c24a9e74d
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/ActionResultException.java
@@ -0,0 +1,41 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.fixes;
+
+import net.minecraft.util.ActionResult;
+
+public class ActionResultException extends RuntimeException {
+
+ private final ActionResult actionResult;
+
+ public ActionResultException(final ActionResult actionResult) {
+ this.actionResult = actionResult;
+ }
+
+ public ActionResult getActionResult() {
+ return this.actionResult;
+ }
+
+ @Override
+ public synchronized Throwable fillInStackTrace() {
+ return this;
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/ArmorUpdateListener.java b/src/main/java/de/florianmichael/viafabricplus/fixes/ArmorUpdateListener.java
new file mode 100644
index 000000000..731c42bcf
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/ArmorUpdateListener.java
@@ -0,0 +1,67 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.fixes;
+
+import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
+import com.viaversion.viaversion.api.type.Type;
+import com.viaversion.viaversion.protocols.protocol1_9to1_8.ArmorType;
+import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
+import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
+import de.florianmichael.viafabricplus.ViaFabricPlus;
+import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.item.ItemStack;
+import net.minecraft.registry.Registries;
+
+public class ArmorUpdateListener {
+
+ public static void init() {
+ ClientTickEvents.START_WORLD_TICK.register(world -> {
+ if (MinecraftClient.getInstance().player != null) {
+ try {
+ sendArmorUpdate();
+ } catch (Throwable t) {
+ ViaFabricPlus.global().getLogger().error("Error sending armor update", t);
+ }
+ }
+ });
+ }
+
+ public static void sendArmorUpdate() throws Exception {
+ int armor = 0;
+ for (final ItemStack stack : MinecraftClient.getInstance().player.getInventory().armor) {
+ armor += ArmorType.findByType(Registries.ITEM.getId(stack.getItem()).toString()).getArmorPoints();
+ }
+ if (armor == this.oldArmor) return;
+
+ this.oldArmor = armor;
+ final PacketWrapper properties = PacketWrapper.create(ClientboundPackets1_9.ENTITY_PROPERTIES, MinecraftClient.getInstance().getNetworkHandler().getConnection().getUserConnection());
+ properties.write(Type.VAR_INT, MinecraftClient.getInstance().player.getId());
+ properties.write(Type.INT, 1);
+ properties.write(Type.STRING, "generic.armor");
+ properties.write(Type.DOUBLE, 0D);
+ properties.write(Type.VAR_INT, 1);
+ properties.write(Type.UUID, ARMOR_POINTS_UUID);
+ properties.write(Type.DOUBLE, (double) armor);
+ properties.write(Type.BYTE, (byte) 0);
+ properties.scheduleSend(Protocol1_9To1_8.class);
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/ChestHandler1_13_2.java b/src/main/java/de/florianmichael/viafabricplus/fixes/ChestHandler1_13_2.java
new file mode 100644
index 000000000..674eed543
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/ChestHandler1_13_2.java
@@ -0,0 +1,50 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.fixes;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
+import net.minecraft.inventory.SimpleInventory;
+import net.minecraft.network.PacketByteBuf;
+import net.minecraft.screen.GenericContainerScreenHandler;
+import net.minecraft.text.Text;
+import net.minecraft.util.math.MathHelper;
+
+import java.util.function.Consumer;
+
+public class ChestHandler1_13_2 {
+
+ public static final Consumer OLD_PACKET_HANDLER = data -> {
+ final MinecraftClient mc = MinecraftClient.getInstance();
+
+ try {
+ final int windowId = data.readUnsignedByte();
+ final int slots = data.readUnsignedByte();
+ final Text title = data.readText();
+
+ final GenericContainerScreenHandler screenHandler = new GenericContainerScreenHandler(null, windowId, mc.player.getInventory(), new SimpleInventory(slots), MathHelper.ceil(slots / 9F));
+ mc.player.currentScreenHandler = screenHandler;
+ mc.setScreen(new GenericContainerScreen(screenHandler, mc.player.getInventory(), title));
+ } catch (Throwable t) {
+ throw new RuntimeException("Failed to handle OpenWindow packet data", t);
+ }
+ };
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/ClientPlayerInteractionManager1_18_2.java b/src/main/java/de/florianmichael/viafabricplus/fixes/ClientPlayerInteractionManager1_18_2.java
index c1d38df3d..7cdb3d893 100644
--- a/src/main/java/de/florianmichael/viafabricplus/fixes/ClientPlayerInteractionManager1_18_2.java
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/ClientPlayerInteractionManager1_18_2.java
@@ -21,7 +21,7 @@
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
-import de.florianmichael.viafabricplus.protocolhack.util.BlockStateTranslator;
+import de.florianmichael.viafabricplus.protocolhack.translator.BlockStateTranslator;
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@@ -33,62 +33,62 @@
import net.minecraft.util.math.Vec2f;
import net.raphimc.vialoader.util.VersionEnum;
-import java.util.Objects;
import java.util.function.Consumer;
public class ClientPlayerInteractionManager1_18_2 {
+
public static final Consumer OLD_PACKET_HANDLER = data -> {
try {
final var pos = data.readBlockPos();
- final var blockState = Block.STATE_IDS.get(BlockStateTranslator.translateBlockState1_18(data.readVarInt()));
+ final var blockState = BlockStateTranslator.via1_18_2toMc(data.readVarInt());
final var action = data.readEnumConstant(PlayerActionC2SPacket.Action.class);
final var allGood = data.readBoolean();
ClientPlayerInteractionManager1_18_2.handleBlockBreakAck(pos, blockState, action, allGood);
- } catch (Exception e) {
- ViaFabricPlus.global().getLogger().error("Failed to read BlockBreakAck packet data", e);
+ } catch (Throwable t) {
+ throw new RuntimeException("Failed to handle BlockBreakAck packet data", t);
}
};
- private static final Object2ObjectLinkedOpenHashMap, PositionAndRotation> UN_ACKED_ACTIONS = new Object2ObjectLinkedOpenHashMap<>();
+ private static final Object2ObjectLinkedOpenHashMap, PositionAndRotation> UNACKED_ACTIONS = new Object2ObjectLinkedOpenHashMap<>();
- public static void trackBlockAction(final PlayerActionC2SPacket.Action action, final BlockPos blockPos) {
+ public static void trackPlayerAction(final PlayerActionC2SPacket.Action action, final BlockPos blockPos) {
final var player = MinecraftClient.getInstance().player;
if (player == null) return;
var rotation = new Vec2f(player.getYaw(), player.getPitch());
- if (ProtocolHack.getTargetVersion().isNewerThan(VersionEnum.r1_16_2)) {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_1)) {
rotation = null;
}
- UN_ACKED_ACTIONS.put(new Pair<>(blockPos, action), new PositionAndRotation(player.getPos().x, player.getPos().y, player.getPos().z, rotation));
+ UNACKED_ACTIONS.put(new Pair<>(blockPos, action), new PositionAndRotation(player.getPos().x, player.getPos().y, player.getPos().z, rotation));
}
- public static void handleBlockBreakAck(final BlockPos blockPos, final BlockState blockState, final PlayerActionC2SPacket.Action action, final boolean allGood) {
+ public static void handleBlockBreakAck(final BlockPos blockPos, final BlockState expectedState, final PlayerActionC2SPacket.Action action, final boolean allGood) {
final var player = MinecraftClient.getInstance().player;
if (player == null) return;
+ final var world = MinecraftClient.getInstance().getNetworkHandler().getWorld();
- final var world = Objects.requireNonNull(MinecraftClient.getInstance().getNetworkHandler()).getWorld();
-
- final var next = UN_ACKED_ACTIONS.remove(new Pair<>(blockPos, action));
- final var blockStateFromPos = world.getBlockState(blockPos);
+ final var oldPlayerState = UNACKED_ACTIONS.remove(new Pair<>(blockPos, action));
+ final var actualState = world.getBlockState(blockPos);
- if ((next == null || !allGood || action != PlayerActionC2SPacket.Action.START_DESTROY_BLOCK && blockStateFromPos != blockState) && blockStateFromPos != blockState) {
- world.setBlockState(blockPos, blockState);
- if (next != null && world == player.getWorld() && player.collidesWithStateAtPos(blockPos, blockState)) {
- if (next.rotation != null) {
- player.updatePositionAndAngles(next.x, next.y, next.z, next.rotation.x, next.rotation.y);
+ if ((oldPlayerState == null || !allGood || action != PlayerActionC2SPacket.Action.START_DESTROY_BLOCK && actualState != expectedState) && (actualState != expectedState || ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_15_2))) {
+ world.setBlockState(blockPos, expectedState, Block.NOTIFY_ALL | Block.FORCE_STATE);
+ if (oldPlayerState != null && ((ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_1) || (world == player.getWorld() && player.collidesWithStateAtPos(blockPos, expectedState))))) {
+ if (oldPlayerState.rotation != null) {
+ player.updatePositionAndAngles(oldPlayerState.x, oldPlayerState.y, oldPlayerState.z, oldPlayerState.rotation.x, oldPlayerState.rotation.y);
} else {
- player.updatePosition(next.x, next.y, next.z);
+ player.updatePosition(oldPlayerState.x, oldPlayerState.y, oldPlayerState.z);
}
}
}
- while (UN_ACKED_ACTIONS.size() >= 50) {
- ViaFabricPlus.global().getLogger().error("Too many unacked block actions, dropping {}", UN_ACKED_ACTIONS.firstKey());
- UN_ACKED_ACTIONS.removeFirst();
+ while (UNACKED_ACTIONS.size() >= 50) {
+ ViaFabricPlus.global().getLogger().warn("Too many unacked block actions, dropping {}", UNACKED_ACTIONS.firstKey());
+ UNACKED_ACTIONS.removeFirst();
}
}
public record PositionAndRotation(double x, double y, double z, Vec2f rotation) {
}
+
}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/ClientsideFixes.java b/src/main/java/de/florianmichael/viafabricplus/fixes/ClientsideFixes.java
index a231ba88b..cd51339ee 100644
--- a/src/main/java/de/florianmichael/viafabricplus/fixes/ClientsideFixes.java
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/ClientsideFixes.java
@@ -19,28 +19,22 @@
package de.florianmichael.viafabricplus.fixes;
-import com.viaversion.viaversion.protocols.protocol1_9to1_8.ArmorType;
import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback;
-import de.florianmichael.viafabricplus.event.PostGameLoadCallback;
import de.florianmichael.viafabricplus.event.LoadClassicProtocolExtensionCallback;
import de.florianmichael.viafabricplus.fixes.classic.CustomClassicProtocolExtensions;
import de.florianmichael.viafabricplus.fixes.classic.screen.ClassicItemSelectionScreen;
import de.florianmichael.viafabricplus.injection.ViaFabricPlusMixinPlugin;
-import net.minecraft.block.Block;
-import net.minecraft.block.BlockState;
-import net.minecraft.block.Blocks;
+import net.minecraft.block.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.FontStorage;
-import net.minecraft.item.Item;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.Items;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.registry.Registries;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.data.ClassicProtocolExtension;
import net.raphimc.vialoader.util.VersionEnum;
-import net.raphimc.vialoader.util.VersionRange;
-import java.util.*;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
@@ -54,16 +48,6 @@ public class ClientsideFixes {
*/
private static List RELOADABLE_BLOCKS;
- /**
- * Legacy versions do not support SRV records, so we need to resolve them manually
- */
- public static final VersionRange LEGACY_SRV_RESOLVE = VersionRange.andOlder(VersionEnum.r1_2_4tor1_2_5).add(VersionRange.single(VersionEnum.bedrockLatest));
-
- /**
- * Contains the armor points of all armor items in legacy versions (<= 1.8.x)
- */
- private static final Map- LEGACY_ARMOR_POINTS = new HashMap<>();
-
/**
* Contains all tasks that are waiting for a packet to be received, this system can be used to sync ViaVersion tasks with the correct thread
*/
@@ -74,63 +58,59 @@ public class ClientsideFixes {
*/
public static final String PACKET_SYNC_IDENTIFIER = UUID.randomUUID() + ":" + UUID.randomUUID();
+ private static final float DEFAULT_SOUL_SAND_VELOCITY_MULTIPLIER = Blocks.SOUL_SAND.getVelocityMultiplier();
+ private static final float _1_14_4_SOUL_SAND_VELOCITY_MULTIPLIER = 1F;
+
/**
* The current chat limit
*/
- private static int currentChatLimit = 256;
+ private static int currentChatLength = 256;
public static void init() {
CustomClassicProtocolExtensions.create();
-
- PostGameLoadCallback.EVENT.register(() -> {
- // Loads the armor points of all armor items in legacy versions (<= 1.8.x)
- for (Item armorItem : Arrays.asList(Items.LEATHER_HELMET, Items.LEATHER_CHESTPLATE, Items.LEATHER_BOOTS,
- Items.CHAINMAIL_HELMET, Items.CHAINMAIL_CHESTPLATE, Items.CHAINMAIL_LEGGINGS, Items.CHAINMAIL_BOOTS,
- Items.IRON_HELMET, Items.IRON_CHESTPLATE, Items.IRON_LEGGINGS, Items.IRON_BOOTS, Items.DIAMOND_HELMET,
- Items.DIAMOND_CHESTPLATE, Items.DIAMOND_LEGGINGS, Items.DIAMOND_BOOTS, Items.GOLDEN_HELMET,
- Items.GOLDEN_CHESTPLATE, Items.GOLDEN_LEGGINGS, Items.GOLDEN_BOOTS)) {
- LEGACY_ARMOR_POINTS.put(armorItem, ArmorType.findByType(Registries.ITEM.getId(armorItem).toString()).getArmorPoints());
- }
-
- RELOADABLE_BLOCKS = Arrays.asList(Blocks.ANVIL, Blocks.WHITE_BED, Blocks.ORANGE_BED,
- Blocks.MAGENTA_BED, Blocks.LIGHT_BLUE_BED, Blocks.YELLOW_BED, Blocks.LIME_BED, Blocks.PINK_BED, Blocks.GRAY_BED,
- Blocks.LIGHT_GRAY_BED, Blocks.CYAN_BED, Blocks.PURPLE_BED, Blocks.BLUE_BED, Blocks.BROWN_BED, Blocks.GREEN_BED,
- Blocks.RED_BED, Blocks.BLACK_BED, Blocks.BREWING_STAND, Blocks.CAULDRON, Blocks.CHEST, Blocks.PITCHER_CROP,
- Blocks.END_PORTAL, Blocks.END_PORTAL_FRAME, Blocks.FARMLAND, Blocks.OAK_FENCE, Blocks.HOPPER, Blocks.LADDER,
- Blocks.LILY_PAD, Blocks.GLASS_PANE, Blocks.WHITE_STAINED_GLASS_PANE, Blocks.ORANGE_STAINED_GLASS_PANE,
- Blocks.MAGENTA_STAINED_GLASS_PANE, Blocks.LIGHT_BLUE_STAINED_GLASS_PANE, Blocks.YELLOW_STAINED_GLASS_PANE,
- Blocks.LIME_STAINED_GLASS_PANE, Blocks.PINK_STAINED_GLASS_PANE, Blocks.GRAY_STAINED_GLASS_PANE,
- Blocks.LIGHT_GRAY_STAINED_GLASS_PANE, Blocks.CYAN_STAINED_GLASS_PANE, Blocks.PURPLE_STAINED_GLASS_PANE,
- Blocks.BLUE_STAINED_GLASS_PANE, Blocks.BROWN_STAINED_GLASS_PANE, Blocks.GREEN_STAINED_GLASS_PANE,
- Blocks.RED_STAINED_GLASS_PANE, Blocks.BLACK_STAINED_GLASS_PANE, Blocks.PISTON, Blocks.PISTON_HEAD,
- Blocks.SNOW, Blocks.COBBLESTONE_WALL, Blocks.MOSSY_COBBLESTONE_WALL
- );
- });
+ EntityHitboxUpdateListener.init();
+ ArmorUpdateListener.init();
// Reloads some clientside stuff when the protocol version changes
ChangeProtocolVersionCallback.EVENT.register((oldVersion, newVersion) -> MinecraftClient.getInstance().execute(() -> {
- if (MinecraftClient.getInstance() == null) return;
+ // Soul sand velocity multiplier
+ if (isNewerThan(oldVersion, newVersion, VersionEnum.r1_14_4)) {
+ Blocks.SOUL_SAND.velocityMultiplier = DEFAULT_SOUL_SAND_VELOCITY_MULTIPLIER;
+ }
+ if (isOlderThanOrEqualTo(oldVersion, newVersion, VersionEnum.r1_14_4)) {
+ Blocks.SOUL_SAND.velocityMultiplier = _1_14_4_SOUL_SAND_VELOCITY_MULTIPLIER;
+ }
// Reloads all bounding boxes
- for (Block block : RELOADABLE_BLOCKS) {
- for (BlockState state : block.getStateManager().getStates()) {
- state.initShapeCache();
+ for (Block block : Registries.BLOCK) {
+ if (block instanceof AnvilBlock || block instanceof BedBlock || block instanceof BrewingStandBlock
+ || block instanceof CarpetBlock || block instanceof CauldronBlock || block instanceof ChestBlock
+ || block instanceof EnderChestBlock || block instanceof EndPortalBlock || block instanceof EndPortalFrameBlock
+ || block instanceof FarmlandBlock || block instanceof FenceBlock || block instanceof FenceGateBlock
+ || block instanceof HopperBlock || block instanceof LadderBlock || block instanceof LeavesBlock
+ || block instanceof LilyPadBlock || block instanceof PaneBlock || block instanceof PistonBlock
+ || block instanceof PistonHeadBlock || block instanceof SnowBlock || block instanceof WallBlock
+ || block instanceof CropBlock || block instanceof FlowerbedBlock
+ ) {
+ for (BlockState state : block.getStateManager().getStates()) {
+ state.initShapeCache();
+ }
}
}
- // Calculates the current chat limit, since it changes depending on the protocol version
+ // Calculates the current chat length limit
if (newVersion.isOlderThanOrEqualTo(VersionEnum.c0_28toc0_30)) {
- currentChatLimit = 64 - (MinecraftClient.getInstance().getSession().getUsername().length() + 2);
+ currentChatLength = 64 - (MinecraftClient.getInstance().getSession().getUsername().length() + 2);
} else if (newVersion.equals(VersionEnum.bedrockLatest)) {
- currentChatLimit = 512;
+ currentChatLength = 512;
} else if (newVersion.isOlderThanOrEqualTo(VersionEnum.r1_9_3tor1_9_4)) {
- currentChatLimit = 100;
+ currentChatLength = 100;
} else {
- currentChatLimit = 256;
+ currentChatLength = 256;
}
+ // Text Renderer invisible character fix
if (!ViaFabricPlusMixinPlugin.DASH_LOADER_PRESENT) {
- // Reloads all font storages to fix the font renderer
for (FontStorage storage : MinecraftClient.getInstance().fontManager.fontStorages.values()) {
storage.glyphRendererCache.clear();
storage.glyphCache.clear();
@@ -145,7 +125,7 @@ public static void init() {
// Calculates the current chat limit, since it changes depending on the protocol version
LoadClassicProtocolExtensionCallback.EVENT.register(classicProtocolExtension -> {
if (classicProtocolExtension == ClassicProtocolExtension.LONGER_MESSAGES) {
- currentChatLimit = Short.MAX_VALUE * 2;
+ currentChatLength = Short.MAX_VALUE * 2;
}
});
}
@@ -163,33 +143,30 @@ public static String executeSyncTask(final Consumer task) {
}
public static void handleSyncTask(final PacketByteBuf buf) {
- buf.resetReaderIndex();
-
final var uuid = buf.readString();
if (PENDING_EXECUTION_TASKS.containsKey(uuid)) {
MinecraftClient.getInstance().execute(() -> { // Execute the task on the main thread
- final var task = PENDING_EXECUTION_TASKS.get(uuid);
- PENDING_EXECUTION_TASKS.remove(uuid);
-
+ final var task = PENDING_EXECUTION_TASKS.remove(uuid);
task.accept(buf);
});
}
}
- /**
- * Returns the armor points of an armor item in legacy versions (<= 1.8.x)
- *
- * @param itemStack The item stack to get the armor points from
- * @return The armor points of the item stack
- */
- public static int getLegacyArmorPoints(final ItemStack itemStack) {
- if (!LEGACY_ARMOR_POINTS.containsKey(itemStack.getItem())) return 0; // Just in case
+ public static int getCurrentChatLength() {
+ return currentChatLength;
+ }
- return LEGACY_ARMOR_POINTS.get(itemStack.getItem());
+ private static boolean isOlderThanOrEqualTo(final VersionEnum oldVersion, final VersionEnum newVersion, final VersionEnum toCheck) {
+ return oldVersion.isNewerThan(toCheck) && newVersion.isOlderThanOrEqualTo(toCheck);
}
- public static int getCurrentChatLimit() {
- return currentChatLimit;
+ private static boolean isNewerThan(final VersionEnum oldVersion, final VersionEnum newVersion, final VersionEnum toCheck) {
+ return newVersion.isNewerThan(toCheck) && oldVersion.isOlderThanOrEqualTo(toCheck);
}
+
+ private static boolean didCrossBoundary(final VersionEnum oldVersion, final VersionEnum newVersion, final VersionEnum toCheck) {
+ return isNewerThan(oldVersion, newVersion, toCheck) || isOlderThanOrEqualTo(oldVersion, newVersion, toCheck);
+ }
+
}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/EntityHeightOffsetsPre1_20_2.java b/src/main/java/de/florianmichael/viafabricplus/fixes/EntityHeightOffsetsPre1_20_2.java
index 4c98ecde3..ea1e9950c 100644
--- a/src/main/java/de/florianmichael/viafabricplus/fixes/EntityHeightOffsetsPre1_20_2.java
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/EntityHeightOffsetsPre1_20_2.java
@@ -39,144 +39,141 @@
public class EntityHeightOffsetsPre1_20_2 {
public static Vector3f getMountedHeightOffset(final Entity entity, final Entity passenger) {
- double yOffset = entity.getHeight() * 0.75;
+ float yOffset = entity.getHeight() * 0.75F;
- if (entity instanceof LlamaEntity llamaEntity) {
- yOffset = entity.getHeight() * 0.6;
+ if (entity instanceof BoatEntity boatEntity) {
+ if (!boatEntity.hasPassenger(passenger)) return new Vector3f();
- final float xOffset = MathHelper.sin(llamaEntity.bodyYaw * 0.017453292F);
- final float zOffset = MathHelper.cos(llamaEntity.bodyYaw * 0.017453292F);
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
+ yOffset = -0.3F;
+ final float xOffset = MathHelper.cos(boatEntity.getYaw() * MathHelper.PI / 180F);
+ final float zOffset = MathHelper.sin(boatEntity.getYaw() * MathHelper.PI / 180F);
- return new Vector3f(0.3F * xOffset, (float) yOffset, -(0.3F * zOffset));
- } else if (entity instanceof CamelEntity camelEntity) {
- yOffset = entity.getDimensions(camelEntity.isSitting() ? EntityPose.SITTING : EntityPose.STANDING).height - (camelEntity.isBaby() ? 0.35F : 0.6F);
-
- final int passengerIndex = camelEntity.getPassengerList().indexOf(passenger);
- final boolean firstIndex = passengerIndex == 0;
- if (passengerIndex >= 0) {
- float zOffset = 0.5f;
- if (camelEntity.isRemoved()) {
- yOffset = 0.01f;
+ return new Vector3f(0.4F * xOffset, yOffset, 0.4F * zOffset);
+ } else {
+ if (boatEntity.isRemoved()) {
+ yOffset = 0.01F;
} else {
- final var fakeDimension = EntityDimensions.fixed(0F, (0.375F * camelEntity.getScaleFactor()) + (float) yOffset); // Reverts original calculation to set yOffset to our field
- yOffset = camelEntity.getPassengerAttachmentY(firstIndex, 0.0f, fakeDimension, camelEntity.getScaleFactor());
+ yOffset = boatEntity.getVariant() == BoatEntity.Type.BAMBOO ? 0.25F : -0.1F;
}
- if (camelEntity.getPassengerList().size() > 1) {
- if (!firstIndex) zOffset = -0.7f;
- if (passenger instanceof AnimalEntity) zOffset += 0.2f;
+ float xOffset = boatEntity instanceof ChestBoatEntity ? 0.15F : 0F;
+ if (boatEntity.getPassengerList().size() > 1) {
+ final int idx = boatEntity.getPassengerList().indexOf(passenger);
+ if (idx == 0) {
+ xOffset = 0.2F;
+ } else {
+ xOffset = -0.6F;
+ }
+
+ if (passenger instanceof AnimalEntity) xOffset += 0.2F;
}
- return new Vector3f(0, (float) yOffset, zOffset);
- } else {
- return new Vector3f();
+ return new Vector3f(xOffset, yOffset, 0F);
}
- } else if (entity instanceof SnifferEntity) {
- yOffset = 1.8;
- } else if (entity instanceof EnderDragonEntity enderDragonEntity) {
- yOffset = enderDragonEntity.body.getHeight();
- } else if (entity instanceof PiglinEntity) {
- yOffset = entity.getHeight() * 0.92;
- } else if (entity instanceof HoglinEntity hoglinEntity) {
- yOffset = entity.getHeight() - (hoglinEntity.isBaby() ? 0.2 : 0.15);
- } else if (entity instanceof SkeletonHorseEntity) {
- yOffset -= 0.1875;
- } else if (entity instanceof PhantomEntity) {
- yOffset = entity.getEyeHeight(entity.getPose());
- } else if (entity instanceof RavagerEntity) {
- yOffset = 2.1;
- } else if (entity instanceof ZoglinEntity zoglinEntity) {
- yOffset = (double) entity.getHeight() - (zoglinEntity.isBaby() ? 0.2 : 0.15);
- } else if (entity instanceof BoatEntity boatEntity) {
- final var version = ProtocolHack.getTargetVersion();
- if (version.isOlderThanOrEqualTo(VersionEnum.r1_8)) {
- yOffset = -0.3;
+ } else if (entity instanceof CamelEntity camelEntity) {
+ if (!camelEntity.hasPassenger(passenger)) return new Vector3f();
+
+ final boolean firstPassenger = camelEntity.getPassengerList().indexOf(passenger) == 0;
+ yOffset = camelEntity.getDimensions(camelEntity.isSitting() ? EntityPose.SITTING : EntityPose.STANDING).height - (camelEntity.isBaby() ? 0.35F : 0.6F);
+ if (camelEntity.isRemoved()) {
+ yOffset = 0.01F;
} else {
- yOffset = boatEntity.getVariant() == BoatEntity.Type.BAMBOO ? 0.25 : -0.1;
+ yOffset = (float) camelEntity.getPassengerAttachmentY(firstPassenger, 0F, EntityDimensions.fixed(0F, (0.375F * camelEntity.getScaleFactor()) + yOffset), camelEntity.getScaleFactor());
}
- if (boatEntity.hasPassenger(passenger)) {
- float xOffset = (boatEntity instanceof ChestBoatEntity) ? 0.15F : 0.0F;
- yOffset = (boatEntity.isRemoved() ? (double) 0.01f : yOffset);
+ float zOffset = 0.5F;
+ if (camelEntity.getPassengerList().size() > 1) {
+ if (!firstPassenger) zOffset = -0.7F;
+ if (passenger instanceof AnimalEntity) zOffset += 0.2F;
+ }
- if (boatEntity.getPassengerList().size() > 1) {
- int i = boatEntity.getPassengerList().indexOf(passenger);
- xOffset = i == 0 ? 0.2f : -0.6f;
- if (passenger instanceof AnimalEntity) {
- xOffset += 0.2f;
- }
- }
+ return new Vector3f(0, yOffset, zOffset);
+ } else if (entity instanceof ChickenEntity chickenEntity) {
+ final float xOffset = MathHelper.sin(chickenEntity.bodyYaw * MathHelper.PI / 180F);
+ final float zOffset = MathHelper.cos(chickenEntity.bodyYaw * MathHelper.PI / 180F);
- return new Vector3f(xOffset, (float) yOffset, 0.0F);
- } else {
- return new Vector3f();
- }
- } else if (entity instanceof StriderEntity striderEntity) {
- final var var1 = Math.min(0.25F, striderEntity.limbAnimator.getSpeed());
- final var var2 = striderEntity.limbAnimator.getPos();
+ return new Vector3f(0.1F * xOffset, (float) (chickenEntity.getBodyY(0.5D) - chickenEntity.getY()), -0.1F * zOffset);
+ } else if (entity instanceof EnderDragonEntity enderDragonEntity) {
+ yOffset = enderDragonEntity.body.getHeight();
+ } else if (entity instanceof HoglinEntity hoglinEntity) {
+ yOffset = hoglinEntity.getHeight() - (hoglinEntity.isBaby() ? 0.2F : 0.15F);
+ } else if (entity instanceof LlamaEntity llamaEntity) {
+ yOffset = entity.getHeight() * 0.6F;
+ final float xOffset = MathHelper.sin(llamaEntity.bodyYaw * MathHelper.PI / 180F);
+ final float zOffset = MathHelper.cos(llamaEntity.bodyYaw * MathHelper.PI / 180F);
- yOffset = (double) striderEntity.getHeight() - 0.19 + (double) (0.12F * MathHelper.cos(var2 * 1.5F) * 2.0F * var1);
+ return new Vector3f(0.3F * xOffset, yOffset, 0.3F * zOffset);
+ } else if (entity instanceof PhantomEntity) {
+ yOffset = entity.getStandingEyeHeight();
+ } else if (entity instanceof PiglinEntity) {
+ yOffset = entity.getHeight() * 0.92F;
+ } else if (entity instanceof RavagerEntity) {
+ yOffset = 2.1F;
+ } else if (entity instanceof SkeletonHorseEntity) {
+ yOffset -= 0.1875F;
+ } else if (entity instanceof SnifferEntity) {
+ yOffset = 1.8F;
} else if (entity instanceof SpiderEntity) {
yOffset = entity.getHeight() * 0.5F;
- } else if (entity instanceof ChickenEntity chickenEntity) {
- final var xOffset = MathHelper.sin(chickenEntity.bodyYaw * (MathHelper.PI / 180));
- final var zOffset = MathHelper.cos(chickenEntity.bodyYaw * (MathHelper.PI / 180));
-
- return new Vector3f(0.1f * xOffset, (float) (chickenEntity.getBodyY(0.5) - chickenEntity.getY()), -(0.1f * zOffset));
+ } else if (entity instanceof StriderEntity striderEntity) {
+ final float f = Math.min(0.25F, striderEntity.limbAnimator.getSpeed());
+ final float g = striderEntity.limbAnimator.getPos();
+ yOffset = striderEntity.getHeight() - 0.19F + (0.12F * MathHelper.cos(g * 1.5F) * 2F * f);
+ } else if (entity instanceof ZoglinEntity zoglinEntity) {
+ yOffset = zoglinEntity.getHeight() - (zoglinEntity.isBaby() ? 0.2F : 0.15F);
+ } else if (entity instanceof AbstractDonkeyEntity) {
+ yOffset -= 0.25F;
+ } else if (entity instanceof AbstractMinecartEntity) {
+ yOffset = 0F;
}
- if (entity instanceof AbstractDonkeyEntity) {
- yOffset -= 0.25;
- } else if (entity instanceof AbstractMinecartEntity) {
- yOffset = 0.0;
- } else if (entity instanceof AbstractHorseEntity abstractHorseEntity) {
+ if (entity instanceof AbstractHorseEntity abstractHorseEntity) {
if (abstractHorseEntity.lastAngryAnimationProgress > 0.0f) {
- final float xOffset = MathHelper.sin(abstractHorseEntity.bodyYaw * ((float) Math.PI / 180));
- final float zOffset = MathHelper.cos(abstractHorseEntity.bodyYaw * ((float) Math.PI / 180));
-
+ final float xOffset = MathHelper.sin(abstractHorseEntity.bodyYaw * MathHelper.PI / 180F);
+ final float zOffset = MathHelper.cos(abstractHorseEntity.bodyYaw * MathHelper.PI / 180F);
final float xzFactor = 0.7F * abstractHorseEntity.lastAngryAnimationProgress;
- return new Vector3f(xzFactor * xOffset, (float) (yOffset + 0.15F * abstractHorseEntity.lastAngryAnimationProgress), xzFactor * zOffset);
+ return new Vector3f(xzFactor * xOffset, yOffset + 0.15F * abstractHorseEntity.lastAngryAnimationProgress, xzFactor * zOffset);
}
}
- return new Vector3f(0.0F, (float) yOffset, 0.0F);
+ return new Vector3f(0, yOffset, 0);
}
public static double getHeightOffset(final Entity entity) {
- if (entity instanceof ArmorStandEntity armorStandEntity && !armorStandEntity.isMarker()) {
- return 0.1;
- } else if (entity instanceof EndermiteEntity) {
- return 0.1;
- } else if (entity instanceof ShulkerEntity shulkerEntity) {
- final var vehicleType = shulkerEntity.getVehicle().getType();
-
- return !(shulkerEntity.getVehicle() instanceof BoatEntity) && vehicleType != EntityType.MINECART ? 0 : 0.1875 - getMountedHeightOffset(shulkerEntity.getVehicle(), null).y;
- } else if (entity instanceof SilverfishEntity) {
- return 0.1;
- } else if (entity instanceof AllayEntity || entity instanceof VexEntity) {
+ if (entity instanceof AllayEntity || entity instanceof VexEntity) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_1tor1_19_2)) {
return 0D;
}
- return 0.4;
+ return 0.4D;
+ } else if (entity instanceof ArmorStandEntity armorStandEntity) {
+ return armorStandEntity.isMarker() ? 0D : 0.1D;
+ } else if (entity instanceof EndermiteEntity) {
+ return 0.1D;
+ } else if (entity instanceof ShulkerEntity shulkerEntity) {
+ final EntityType> vehicleType = shulkerEntity.getVehicle().getType();
+ return !(shulkerEntity.getVehicle() instanceof BoatEntity) && vehicleType != EntityType.MINECART ? 0D : 0.1875D - getMountedHeightOffset(shulkerEntity.getVehicle(), null).y;
+ } else if (entity instanceof SilverfishEntity) {
+ return 0.1D;
} else if (entity instanceof ZombifiedPiglinEntity zombifiedPiglinEntity) {
- return zombifiedPiglinEntity.isBaby() ? -0.05 : -0.45;
+ return zombifiedPiglinEntity.isBaby() ? -0.05D : -0.45D;
} else if (entity instanceof ZombieEntity zombieEntity) {
- return zombieEntity.isBaby() ? 0.0 : -0.45;
- }
-
- if (entity instanceof PlayerEntity) {
- return -0.35;
+ return zombieEntity.isBaby() ? 0D : -0.45D;
+ } else if (entity instanceof AnimalEntity) {
+ return 0.14D;
} else if (entity instanceof PatrolEntity) {
- return -0.45;
+ return -0.45D;
+ } else if (entity instanceof PlayerEntity) {
+ return -0.35D;
} else if (entity instanceof AbstractPiglinEntity abstractPiglinEntity) {
- return abstractPiglinEntity.isBaby() ? -0.05 : -0.45;
+ return abstractPiglinEntity.isBaby() ? -0.05D : -0.45D;
} else if (entity instanceof AbstractSkeletonEntity) {
- return -0.6;
- } else if (entity instanceof AnimalEntity) {
- return 0.14;
+ return -0.6D;
}
- return 0;
+
+ return 0D;
}
+
}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/EntityHitboxUpdateListener.java b/src/main/java/de/florianmichael/viafabricplus/fixes/EntityHitboxUpdateListener.java
new file mode 100644
index 000000000..9f38f66b0
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/EntityHitboxUpdateListener.java
@@ -0,0 +1,162 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.fixes;
+
+import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.entity.EntityDimensions;
+import net.minecraft.entity.EntityType;
+import net.raphimc.vialoader.util.VersionEnum;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public class EntityHitboxUpdateListener {
+
+ private static final Map, Map> ENTITY_DIMENSIONS = linkedHashMap(
+ EntityType.WITHER, linkedHashMap(
+ VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.9F, 4.0F),
+ VersionEnum.r1_8, EntityType.WITHER.getDimensions()
+ ),
+ EntityType.SILVERFISH, linkedHashMap(
+ VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.3F, 0.7F),
+ VersionEnum.r1_8, EntityType.SILVERFISH.getDimensions()
+ ),
+ EntityType.SNOW_GOLEM, linkedHashMap(
+ VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.4F, 1.8F),
+ VersionEnum.r1_8, EntityType.SNOW_GOLEM.getDimensions()
+ ),
+ EntityType.ZOMBIE, linkedHashMap(
+ VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.6F, 1.8F),
+ VersionEnum.r1_8, EntityDimensions.fixed(EntityType.ZOMBIE.getDimensions().width, EntityType.ZOMBIE.getDimensions().height),
+ VersionEnum.r1_9, EntityType.ZOMBIE.getDimensions()
+ ),
+ EntityType.CHICKEN, linkedHashMap(
+ VersionEnum.b1_7tob1_7_3, EntityDimensions.changing(0.3F, 0.4F),
+ VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.3F, 0.7F),
+ VersionEnum.r1_8, EntityType.CHICKEN.getDimensions()
+ ),
+ EntityType.SHEEP, linkedHashMap(
+ VersionEnum.c0_28toc0_30, EntityDimensions.changing(1.4F, 1.72F),
+ VersionEnum.a1_0_15, EntityType.SHEEP.getDimensions()
+ ),
+ EntityType.OCELOT, linkedHashMap(
+ VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.6F, 0.8F),
+ VersionEnum.r1_8, EntityType.OCELOT.getDimensions()
+ ),
+ EntityType.BOAT, linkedHashMap(
+ VersionEnum.r1_8, EntityDimensions.changing(1.5F, 0.6F),
+ VersionEnum.r1_9, EntityType.BOAT.getDimensions()
+ ),
+ EntityType.CREEPER, linkedHashMap(
+ VersionEnum.r1_8, EntityDimensions.changing(0.6F, 1.8F),
+ VersionEnum.r1_9, EntityType.CREEPER.getDimensions()
+ ),
+ EntityType.IRON_GOLEM, linkedHashMap(
+ VersionEnum.r1_8, EntityDimensions.changing(1.4F, 2.9F),
+ VersionEnum.r1_9, EntityType.IRON_GOLEM.getDimensions()
+ ),
+ EntityType.SKELETON, linkedHashMap(
+ VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.6F, 1.8F),
+ VersionEnum.r1_8, EntityDimensions.changing(0.6F, 1.95F),
+ VersionEnum.r1_9, EntityType.SKELETON.getDimensions()
+ ),
+ EntityType.WITHER_SKELETON, linkedHashMap(
+ VersionEnum.r1_4_6tor1_4_7, EntityDimensions.changing(0.72F, 2.16F),
+ VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.72F, 2.34F),
+ VersionEnum.r1_8, EntityDimensions.changing(0.72F, 2.535F),
+ VersionEnum.r1_9, EntityType.WITHER_SKELETON.getDimensions()
+ ),
+ EntityType.COW, linkedHashMap(
+ VersionEnum.r1_8, EntityDimensions.changing(0.9F, 1.3F),
+ VersionEnum.r1_9, EntityType.COW.getDimensions()
+ ),
+ EntityType.HORSE, linkedHashMap(
+ VersionEnum.r1_8, EntityDimensions.changing(1.4F, 1.6F),
+ VersionEnum.r1_9, EntityType.HORSE.getDimensions()
+ ),
+ EntityType.MOOSHROOM, linkedHashMap(
+ VersionEnum.r1_8, EntityDimensions.changing(0.9F, 1.3F),
+ VersionEnum.r1_9, EntityType.MOOSHROOM.getDimensions()
+ ),
+ EntityType.RABBIT, linkedHashMap(
+ VersionEnum.r1_8, EntityDimensions.changing(0.6F, 0.7F),
+ VersionEnum.r1_9, EntityType.RABBIT.getDimensions()
+ ),
+ EntityType.SQUID, linkedHashMap(
+ VersionEnum.r1_8, EntityDimensions.changing(0.95F, 0.95F),
+ VersionEnum.r1_9, EntityType.SQUID.getDimensions()
+ ),
+ EntityType.VILLAGER, linkedHashMap(
+ VersionEnum.r1_8, EntityDimensions.changing(0.6F, 1.8F),
+ VersionEnum.r1_9, EntityType.VILLAGER.getDimensions()
+ ),
+ EntityType.WOLF, linkedHashMap(
+ VersionEnum.r1_1, EntityDimensions.changing(0.8F, 0.8F),
+ VersionEnum.r1_8, EntityDimensions.changing(0.6F, 0.8F),
+ VersionEnum.r1_9, EntityType.WOLF.getDimensions()
+ ),
+ EntityType.DRAGON_FIREBALL, linkedHashMap(
+ VersionEnum.r1_10, EntityDimensions.changing(0.3125F, 0.3125F),
+ VersionEnum.r1_11, EntityType.DRAGON_FIREBALL.getDimensions()
+ ),
+ EntityType.LEASH_KNOT, linkedHashMap(
+ VersionEnum.r1_16_4tor1_16_5, EntityDimensions.changing(0.5F, 0.5F),
+ VersionEnum.r1_17, EntityType.LEASH_KNOT.getDimensions()
+ ),
+ EntityType.SLIME, linkedHashMap(
+ VersionEnum.r1_13_2, EntityDimensions.changing(2F, 2F),
+ VersionEnum.r1_14, EntityType.SLIME.getDimensions()
+ ),
+ EntityType.MAGMA_CUBE, linkedHashMap(
+ VersionEnum.r1_13_2, EntityDimensions.changing(2F, 2F),
+ VersionEnum.r1_14, EntityType.MAGMA_CUBE.getDimensions()
+ ),
+ EntityType.ARROW, linkedHashMap(
+ VersionEnum.c0_28toc0_30, EntityDimensions.changing(0.3F, 0.5F),
+ VersionEnum.a1_0_15, EntityType.ARROW.getDimensions()
+ )
+ );
+
+ public static void init() {
+ ChangeProtocolVersionCallback.EVENT.register((oldVersion, newVersion) -> MinecraftClient.getInstance().execute(() -> ENTITY_DIMENSIONS.forEach((entityType, dimensionMap) -> {
+ for (Map.Entry entry : dimensionMap.entrySet()) {
+ final VersionEnum version = entry.getKey();
+ final EntityDimensions dimensions = entry.getValue();
+ if (oldVersion.isNewerThan(version) && newVersion.isOlderThanOrEqualTo(version)) {
+ entityType.dimensions = dimensions;
+ break;
+ }
+ if (newVersion.isNewerThanOrEqualTo(version) && oldVersion.isOlderThanOrEqualTo(version)) {
+ entityType.dimensions = dimensions;
+ }
+ }
+ })));
+ }
+
+ private static Map linkedHashMap(final Object... objects) {
+ if (objects.length % 2 != 0) throw new IllegalArgumentException("Uneven object count");
+
+ final Map map = new LinkedHashMap<>();
+ for (int i = 0; i < objects.length; i += 2) map.put((K) objects[i], (V) objects[i + 1]);
+ return map;
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/PendingUpdateManager1_18_2.java b/src/main/java/de/florianmichael/viafabricplus/fixes/PendingUpdateManager1_18_2.java
new file mode 100644
index 000000000..585e571ef
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/PendingUpdateManager1_18_2.java
@@ -0,0 +1,62 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.fixes;
+
+import net.minecraft.block.BlockState;
+import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.client.network.PendingUpdateManager;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.util.math.BlockPos;
+
+public class PendingUpdateManager1_18_2 extends PendingUpdateManager {
+
+ @Override
+ public void addPendingUpdate(BlockPos pos, BlockState state, ClientPlayerEntity player) {
+ }
+
+ @Override
+ public boolean hasPendingUpdate(BlockPos pos, BlockState state) {
+ return false;
+ }
+
+ @Override
+ public void processPendingUpdates(int maxProcessableSequence, ClientWorld world) {
+ }
+
+ @Override
+ public PendingUpdateManager incrementSequence() {
+ return this;
+ }
+
+ @Override
+ public void close() {
+ }
+
+ @Override
+ public int getSequence() {
+ return 0;
+ }
+
+ @Override
+ public boolean hasPendingSequence() {
+ return false;
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/TripleChestHandler1_13_2.java b/src/main/java/de/florianmichael/viafabricplus/fixes/TripleChestHandler1_13_2.java
deleted file mode 100644
index 70fa681ea..000000000
--- a/src/main/java/de/florianmichael/viafabricplus/fixes/TripleChestHandler1_13_2.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
- * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
- * Copyright (C) 2023 RK_01/RaphiMC and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package de.florianmichael.viafabricplus.fixes;
-
-import com.viaversion.viaversion.api.type.Type;
-import com.viaversion.viaversion.libs.gson.JsonElement;
-import de.florianmichael.viafabricplus.ViaFabricPlus;
-import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.gui.screen.ingame.HandledScreens;
-import net.minecraft.network.PacketByteBuf;
-import net.minecraft.resource.featuretoggle.FeatureFlags;
-import net.minecraft.resource.featuretoggle.FeatureSet;
-import net.minecraft.screen.GenericContainerScreenHandler;
-import net.minecraft.screen.ScreenHandlerType;
-import net.minecraft.text.Text;
-
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Consumer;
-
-public class TripleChestHandler1_13_2 {
- public static final Consumer TRIPLE_CHEST_HANDLER = data -> {
- final var byteBuf = data.asByteBuf();
-
- try {
- TripleChestHandler1_13_2.handleTripleChestHandler(Type.SHORT.readPrimitive(byteBuf), Type.COMPONENT.read(byteBuf), Type.SHORT.readPrimitive(byteBuf));
- } catch (Exception e) {
- ViaFabricPlus.global().getLogger().error("Failed to open custom ScreenHandler with dimension 9xN", e);
- }
- };
-
- public static void handleTripleChestHandler(final short windowID, final JsonElement title, final short slots) {
- int n = slots / 9;
- final int modulo = slots % 9;
- if (modulo > 0) n++;
-
- final var screenHandler = new AtomicReference>();
- int finalN = n;
- screenHandler.set(new TripleChestScreenHandlerType((syncId, playerInventory) -> new GenericContainerScreenHandler(screenHandler.get(), syncId, playerInventory, finalN), FeatureFlags.VANILLA_FEATURES));
-
- HandledScreens.open(screenHandler.get(), MinecraftClient.getInstance(), windowID, Text.Serializer.fromJson(title.toString()));
- }
-
- public static class TripleChestScreenHandlerType extends ScreenHandlerType {
-
- public TripleChestScreenHandlerType(Factory factory, FeatureSet requiredFeatures) {
- super(factory, requiredFeatures);
- }
- }
-}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/classic/screen/ClassicItemSelectionScreen.java b/src/main/java/de/florianmichael/viafabricplus/fixes/classic/screen/ClassicItemSelectionScreen.java
index c564dbdfe..1fb929b12 100644
--- a/src/main/java/de/florianmichael/viafabricplus/fixes/classic/screen/ClassicItemSelectionScreen.java
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/classic/screen/ClassicItemSelectionScreen.java
@@ -33,7 +33,7 @@
@SuppressWarnings("DataFlowIssue")
public class ClassicItemSelectionScreen extends VFPScreen {
- public static ClassicItemSelectionScreen INSTANCE = new ClassicItemSelectionScreen();
+ public static final ClassicItemSelectionScreen INSTANCE = new ClassicItemSelectionScreen();
private static final int MAX_ROW_DIVIDER = 9;
private static final int ITEM_XY_BOX_DIMENSION_CLASSIC = 25;
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/diff/ItemRegistryDiff.java b/src/main/java/de/florianmichael/viafabricplus/fixes/diff/ItemRegistryDiff.java
new file mode 100644
index 000000000..45e8bff9a
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/diff/ItemRegistryDiff.java
@@ -0,0 +1,1373 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.fixes.diff;
+
+import de.florianmichael.viafabricplus.injection.access.IClientConnection;
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.network.ClientPlayNetworkHandler;
+import net.minecraft.item.Item;
+import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.data.ClassicProtocolExtension;
+import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.storage.ExtensionProtocolMetadataStorage;
+import net.raphimc.vialoader.util.VersionRange;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static net.minecraft.item.Items.*;
+import static net.raphimc.vialoader.util.VersionEnum.*;
+import static net.raphimc.vialoader.util.VersionRange.*;
+
+public class ItemRegistryDiff {
+
+ private static final Map
- ITEM_DIFF = new HashMap<>();
+ private static final List
- EXTENDED_CLASSIC_ITEMS = new ArrayList<>();
+
+ static {
+ ITEM_DIFF.put(CHERRY_LOG, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_WOOD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(STRIPPED_CHERRY_LOG, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(STRIPPED_CHERRY_WOOD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_PLANKS, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_STAIRS, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_SLAB, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_FENCE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_FENCE_GATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_DOOR, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_TRAPDOOR, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_PRESSURE_PLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_BUTTON, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_BLOCK, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(STRIPPED_BAMBOO_BLOCK, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_PLANKS, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_STAIRS, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_SLAB, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_FENCE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_FENCE_GATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_DOOR, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_TRAPDOOR, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_PRESSURE_PLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_BUTTON, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_MOSAIC, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_MOSAIC_STAIRS, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_MOSAIC_SLAB, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_BOAT, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_CHEST_BOAT, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_RAFT, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_CHEST_RAFT, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(MUSIC_DISC_RELIC, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SNIFFER_SPAWN_EGG, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CAMEL_SPAWN_EGG, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CALIBRATED_SCULK_SENSOR, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHISELED_BOOKSHELF, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(DECORATED_POT, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SUSPICIOUS_SAND, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SUSPICIOUS_GRAVEL, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(PIGLIN_HEAD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(OAK_HANGING_SIGN, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SPRUCE_HANGING_SIGN, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BIRCH_HANGING_SIGN, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(JUNGLE_HANGING_SIGN, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(ACACIA_HANGING_SIGN, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_HANGING_SIGN, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(DARK_OAK_HANGING_SIGN, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(MANGROVE_HANGING_SIGN, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_HANGING_SIGN, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CRIMSON_HANGING_SIGN, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(WARPED_HANGING_SIGN, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_LEAVES, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_SAPLING, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(CHERRY_SIGN, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BAMBOO_SIGN, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(TORCHFLOWER, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(TORCHFLOWER_SEEDS, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(PINK_PETALS, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(PITCHER_PLANT, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(PITCHER_POD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SNIFFER_EGG, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BRUSH, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(ANGLER_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(ARCHER_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(ARMS_UP_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BLADE_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BREWER_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(BURN_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(DANGER_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(EXPLORER_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(FRIEND_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(HEART_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(HEARTBREAK_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(HOWL_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(MINER_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(MOURNER_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(PLENTY_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(PRIZE_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SHEAF_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SHELTER_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SKULL_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SNORT_POTTERY_SHERD, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(NETHERITE_UPGRADE_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SENTRY_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(DUNE_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(COAST_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(WILD_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(WARD_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(EYE_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(VEX_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(TIDE_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SNOUT_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(RIB_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SPIRE_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(WAYFINDER_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SHAPER_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(SILENCE_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(RAISER_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+ ITEM_DIFF.put(HOST_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(r1_20tor1_20_1));
+
+ ITEM_DIFF.put(IRON_GOLEM_SPAWN_EGG, andNewer(r1_19_3));
+ ITEM_DIFF.put(SNOW_GOLEM_SPAWN_EGG, andNewer(r1_19_3));
+ ITEM_DIFF.put(WITHER_SPAWN_EGG, andNewer(r1_19_3));
+ ITEM_DIFF.put(ENDER_DRAGON_SPAWN_EGG, andNewer(r1_19_3));
+ ITEM_DIFF.put(SPAWNER, andNewer(r1_19_3));
+
+ ITEM_DIFF.put(OCHRE_FROGLIGHT, andNewer(r1_19));
+ ITEM_DIFF.put(PEARLESCENT_FROGLIGHT, andNewer(r1_19));
+ ITEM_DIFF.put(VERDANT_FROGLIGHT, andNewer(r1_19));
+ ITEM_DIFF.put(FROGSPAWN, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_LEAVES, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_LOG, andNewer(r1_19));
+ ITEM_DIFF.put(STRIPPED_MANGROVE_LOG, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_PLANKS, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_PROPAGULE, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_ROOTS, andNewer(r1_19));
+ ITEM_DIFF.put(MUDDY_MANGROVE_ROOTS, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_WOOD, andNewer(r1_19));
+ ITEM_DIFF.put(STRIPPED_MANGROVE_WOOD, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_BOAT, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_CHEST_BOAT, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_PRESSURE_PLATE, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_TRAPDOOR, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_FENCE_GATE, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_DOOR, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_FENCE, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_SIGN, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_SLAB, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_STAIRS, andNewer(r1_19));
+ ITEM_DIFF.put(MANGROVE_BUTTON, andNewer(r1_19));
+ ITEM_DIFF.put(MUD, andNewer(r1_19));
+ ITEM_DIFF.put(MUD_BRICKS, andNewer(r1_19));
+ ITEM_DIFF.put(MUD_BRICK_WALL, andNewer(r1_19));
+ ITEM_DIFF.put(MUD_BRICK_SLAB, andNewer(r1_19));
+ ITEM_DIFF.put(MUD_BRICK_STAIRS, andNewer(r1_19));
+ ITEM_DIFF.put(PACKED_MUD, andNewer(r1_19));
+ ITEM_DIFF.put(REINFORCED_DEEPSLATE, andNewer(r1_19));
+ ITEM_DIFF.put(SCULK, andNewer(r1_19));
+ ITEM_DIFF.put(SCULK_CATALYST, andNewer(r1_19));
+ ITEM_DIFF.put(SCULK_SHRIEKER, andNewer(r1_19));
+ ITEM_DIFF.put(SCULK_VEIN, andNewer(r1_19));
+ ITEM_DIFF.put(TADPOLE_BUCKET, andNewer(r1_19));
+ ITEM_DIFF.put(DISC_FRAGMENT_5, andNewer(r1_19));
+ ITEM_DIFF.put(ECHO_SHARD, andNewer(r1_19));
+ ITEM_DIFF.put(GOAT_HORN, andNewer(r1_19));
+ ITEM_DIFF.put(MUSIC_DISC_5, andNewer(r1_19));
+ ITEM_DIFF.put(RECOVERY_COMPASS, andNewer(r1_19));
+ ITEM_DIFF.put(OAK_CHEST_BOAT, andNewer(r1_19));
+ ITEM_DIFF.put(SPRUCE_CHEST_BOAT, andNewer(r1_19));
+ ITEM_DIFF.put(BIRCH_CHEST_BOAT, andNewer(r1_19));
+ ITEM_DIFF.put(JUNGLE_CHEST_BOAT, andNewer(r1_19));
+ ITEM_DIFF.put(ACACIA_CHEST_BOAT, andNewer(r1_19));
+ ITEM_DIFF.put(DARK_OAK_CHEST_BOAT, andNewer(r1_19));
+ ITEM_DIFF.put(ALLAY_SPAWN_EGG, andNewer(r1_19));
+ ITEM_DIFF.put(FROG_SPAWN_EGG, andNewer(r1_19));
+ ITEM_DIFF.put(TADPOLE_SPAWN_EGG, andNewer(r1_19));
+ ITEM_DIFF.put(WARDEN_SPAWN_EGG, andNewer(r1_19));
+
+ ITEM_DIFF.put(MUSIC_DISC_OTHERSIDE, andNewer(r1_18tor1_18_1));
+
+ ITEM_DIFF.put(CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(WHITE_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(ORANGE_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(MAGENTA_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(LIGHT_BLUE_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(YELLOW_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(LIME_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(PINK_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(GRAY_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(LIGHT_GRAY_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(CYAN_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(PURPLE_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(BLUE_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(BROWN_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(GREEN_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(RED_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(BLACK_CANDLE, andNewer(r1_17));
+ ITEM_DIFF.put(AMETHYST_BLOCK, andNewer(r1_17));
+ ITEM_DIFF.put(BUDDING_AMETHYST, andNewer(r1_17));
+ ITEM_DIFF.put(AMETHYST_CLUSTER, andNewer(r1_17));
+ ITEM_DIFF.put(LARGE_AMETHYST_BUD, andNewer(r1_17));
+ ITEM_DIFF.put(MEDIUM_AMETHYST_BUD, andNewer(r1_17));
+ ITEM_DIFF.put(SMALL_AMETHYST_BUD, andNewer(r1_17));
+ ITEM_DIFF.put(TUFF, andNewer(r1_17));
+ ITEM_DIFF.put(CALCITE, andNewer(r1_17));
+ ITEM_DIFF.put(TINTED_GLASS, andNewer(r1_17));
+ ITEM_DIFF.put(SCULK_SENSOR, andNewer(r1_17));
+ ITEM_DIFF.put(WEATHERED_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(OXIDIZED_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(EXPOSED_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(COPPER_BLOCK, andNewer(r1_17));
+ ITEM_DIFF.put(COPPER_ORE, andNewer(r1_17));
+ ITEM_DIFF.put(WEATHERED_CUT_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(OXIDIZED_CUT_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(EXPOSED_CUT_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(CUT_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(WEATHERED_CUT_COPPER_STAIRS, andNewer(r1_17));
+ ITEM_DIFF.put(OXIDIZED_CUT_COPPER_STAIRS, andNewer(r1_17));
+ ITEM_DIFF.put(EXPOSED_CUT_COPPER_STAIRS, andNewer(r1_17));
+ ITEM_DIFF.put(CUT_COPPER_STAIRS, andNewer(r1_17));
+ ITEM_DIFF.put(WEATHERED_CUT_COPPER_SLAB, andNewer(r1_17));
+ ITEM_DIFF.put(OXIDIZED_CUT_COPPER_SLAB, andNewer(r1_17));
+ ITEM_DIFF.put(EXPOSED_CUT_COPPER_SLAB, andNewer(r1_17));
+ ITEM_DIFF.put(CUT_COPPER_SLAB, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_COPPER_BLOCK, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_WEATHERED_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_EXPOSED_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_CUT_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_WEATHERED_CUT_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_EXPOSED_CUT_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_CUT_COPPER_STAIRS, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_WEATHERED_CUT_COPPER_STAIRS, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_EXPOSED_CUT_COPPER_STAIRS, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_CUT_COPPER_SLAB, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_WEATHERED_CUT_COPPER_SLAB, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_EXPOSED_CUT_COPPER_SLAB, andNewer(r1_17));
+ ITEM_DIFF.put(LIGHTNING_ROD, andNewer(r1_17));
+ ITEM_DIFF.put(POINTED_DRIPSTONE, andNewer(r1_17));
+ ITEM_DIFF.put(DRIPSTONE_BLOCK, andNewer(r1_17));
+ ITEM_DIFF.put(GLOW_LICHEN, andNewer(r1_17));
+ ITEM_DIFF.put(AZALEA_LEAVES, andNewer(r1_17));
+ ITEM_DIFF.put(SPORE_BLOSSOM, andNewer(r1_17));
+ ITEM_DIFF.put(AZALEA, andNewer(r1_17));
+ ITEM_DIFF.put(FLOWERING_AZALEA, andNewer(r1_17));
+ ITEM_DIFF.put(FLOWERING_AZALEA_LEAVES, andNewer(r1_17));
+ ITEM_DIFF.put(MOSS_CARPET, andNewer(r1_17));
+ ITEM_DIFF.put(MOSS_BLOCK, andNewer(r1_17));
+ ITEM_DIFF.put(BIG_DRIPLEAF, andNewer(r1_17));
+ ITEM_DIFF.put(SMALL_DRIPLEAF, andNewer(r1_17));
+ ITEM_DIFF.put(ROOTED_DIRT, andNewer(r1_17));
+ ITEM_DIFF.put(HANGING_ROOTS, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_GOLD_ORE, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_IRON_ORE, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_LAPIS_ORE, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_DIAMOND_ORE, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_REDSTONE_ORE, andNewer(r1_17));
+ ITEM_DIFF.put(CHISELED_DEEPSLATE, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE, andNewer(r1_17));
+ ITEM_DIFF.put(COBBLED_DEEPSLATE, andNewer(r1_17));
+ ITEM_DIFF.put(COBBLED_DEEPSLATE_STAIRS, andNewer(r1_17));
+ ITEM_DIFF.put(COBBLED_DEEPSLATE_SLAB, andNewer(r1_17));
+ ITEM_DIFF.put(COBBLED_DEEPSLATE_WALL, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_BRICK_SLAB, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_BRICK_STAIRS, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_BRICK_WALL, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_BRICKS, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_TILE_SLAB, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_TILE_STAIRS, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_TILE_WALL, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_TILES, andNewer(r1_17));
+ ITEM_DIFF.put(POLISHED_DEEPSLATE, andNewer(r1_17));
+ ITEM_DIFF.put(POLISHED_DEEPSLATE_SLAB, andNewer(r1_17));
+ ITEM_DIFF.put(POLISHED_DEEPSLATE_STAIRS, andNewer(r1_17));
+ ITEM_DIFF.put(POLISHED_DEEPSLATE_WALL, andNewer(r1_17));
+ ITEM_DIFF.put(SMOOTH_BASALT, andNewer(r1_17));
+ ITEM_DIFF.put(CRACKED_DEEPSLATE_BRICKS, andNewer(r1_17));
+ ITEM_DIFF.put(CRACKED_DEEPSLATE_TILES, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_COAL_ORE, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_COPPER_ORE, andNewer(r1_17));
+ ITEM_DIFF.put(DEEPSLATE_EMERALD_ORE, andNewer(r1_17));
+ ITEM_DIFF.put(INFESTED_DEEPSLATE, andNewer(r1_17));
+ ITEM_DIFF.put(LIGHT, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_OXIDIZED_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_OXIDIZED_CUT_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_OXIDIZED_CUT_COPPER_SLAB, andNewer(r1_17));
+ ITEM_DIFF.put(WAXED_OXIDIZED_CUT_COPPER_STAIRS, andNewer(r1_17));
+ ITEM_DIFF.put(RAW_COPPER_BLOCK, andNewer(r1_17));
+ ITEM_DIFF.put(RAW_GOLD_BLOCK, andNewer(r1_17));
+ ITEM_DIFF.put(RAW_IRON_BLOCK, andNewer(r1_17));
+ ITEM_DIFF.put(COPPER_INGOT, andNewer(r1_17));
+ ITEM_DIFF.put(BUNDLE, andNewer(r1_17));
+ ITEM_DIFF.put(AMETHYST_SHARD, andNewer(r1_17));
+ ITEM_DIFF.put(SPYGLASS, andNewer(r1_17));
+ ITEM_DIFF.put(POWDER_SNOW_BUCKET, andNewer(r1_17));
+ ITEM_DIFF.put(AXOLOTL_BUCKET, andNewer(r1_17));
+ ITEM_DIFF.put(GLOW_ITEM_FRAME, andNewer(r1_17));
+ ITEM_DIFF.put(GLOW_INK_SAC, andNewer(r1_17));
+ ITEM_DIFF.put(GLOW_BERRIES, andNewer(r1_17));
+ ITEM_DIFF.put(RAW_IRON, andNewer(r1_17));
+ ITEM_DIFF.put(RAW_GOLD, andNewer(r1_17));
+ ITEM_DIFF.put(RAW_COPPER, andNewer(r1_17));
+ ITEM_DIFF.put(AXOLOTL_SPAWN_EGG, andNewer(r1_17));
+ ITEM_DIFF.put(GLOW_SQUID_SPAWN_EGG, andNewer(r1_17));
+ ITEM_DIFF.put(GOAT_SPAWN_EGG, andNewer(r1_17));
+
+ ITEM_DIFF.put(ANCIENT_DEBRIS, andNewer(r1_16));
+ ITEM_DIFF.put(BASALT, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_BUTTON, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_BUTTON, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_DOOR, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_DOOR, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_FENCE, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_FENCE, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_FENCE_GATE, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_FENCE_GATE, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_FUNGUS, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_FUNGUS, andNewer(r1_16));
+ ITEM_DIFF.put(NETHER_SPROUTS, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_NYLIUM, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_NYLIUM, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_PLANKS, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_PLANKS, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_PRESSURE_PLATE, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_PRESSURE_PLATE, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_ROOTS, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_ROOTS, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_SIGN, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_SIGN, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_SLAB, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_SLAB, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_STAIRS, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_STAIRS, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_STEM, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_STEM, andNewer(r1_16));
+ ITEM_DIFF.put(STRIPPED_CRIMSON_STEM, andNewer(r1_16));
+ ITEM_DIFF.put(STRIPPED_WARPED_STEM, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_TRAPDOOR, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_TRAPDOOR, andNewer(r1_16));
+ ITEM_DIFF.put(NETHERITE_BLOCK, andNewer(r1_16));
+ ITEM_DIFF.put(SHROOMLIGHT, andNewer(r1_16));
+ ITEM_DIFF.put(SOUL_LANTERN, andNewer(r1_16));
+ ITEM_DIFF.put(SOUL_TORCH, andNewer(r1_16));
+ ITEM_DIFF.put(SOUL_SOIL, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_WART_BLOCK, andNewer(r1_16));
+ ITEM_DIFF.put(WEEPING_VINES, andNewer(r1_16));
+ ITEM_DIFF.put(TARGET, andNewer(r1_16));
+ ITEM_DIFF.put(CRYING_OBSIDIAN, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_HYPHAE, andNewer(r1_16));
+ ITEM_DIFF.put(STRIPPED_WARPED_HYPHAE, andNewer(r1_16));
+ ITEM_DIFF.put(CRIMSON_HYPHAE, andNewer(r1_16));
+ ITEM_DIFF.put(STRIPPED_CRIMSON_HYPHAE, andNewer(r1_16));
+ ITEM_DIFF.put(NETHER_GOLD_ORE, andNewer(r1_16));
+ ITEM_DIFF.put(TWISTING_VINES, andNewer(r1_16));
+ ITEM_DIFF.put(POLISHED_BASALT, andNewer(r1_16));
+ ITEM_DIFF.put(RESPAWN_ANCHOR, andNewer(r1_16));
+ ITEM_DIFF.put(LODESTONE, andNewer(r1_16));
+ ITEM_DIFF.put(CHAIN, andNewer(r1_16));
+ ITEM_DIFF.put(SOUL_CAMPFIRE, andNewer(r1_16));
+ ITEM_DIFF.put(BLACKSTONE, andNewer(r1_16));
+ ITEM_DIFF.put(BLACKSTONE_STAIRS, andNewer(r1_16));
+ ITEM_DIFF.put(BLACKSTONE_WALL, andNewer(r1_16));
+ ITEM_DIFF.put(BLACKSTONE_SLAB, andNewer(r1_16));
+ ITEM_DIFF.put(POLISHED_BLACKSTONE, andNewer(r1_16));
+ ITEM_DIFF.put(POLISHED_BLACKSTONE_BRICKS, andNewer(r1_16));
+ ITEM_DIFF.put(CRACKED_POLISHED_BLACKSTONE_BRICKS, andNewer(r1_16));
+ ITEM_DIFF.put(CHISELED_POLISHED_BLACKSTONE, andNewer(r1_16));
+ ITEM_DIFF.put(POLISHED_BLACKSTONE_BRICK_SLAB, andNewer(r1_16));
+ ITEM_DIFF.put(POLISHED_BLACKSTONE_BRICK_STAIRS, andNewer(r1_16));
+ ITEM_DIFF.put(POLISHED_BLACKSTONE_BRICK_WALL, andNewer(r1_16));
+ ITEM_DIFF.put(GILDED_BLACKSTONE, andNewer(r1_16));
+ ITEM_DIFF.put(POLISHED_BLACKSTONE_STAIRS, andNewer(r1_16));
+ ITEM_DIFF.put(POLISHED_BLACKSTONE_SLAB, andNewer(r1_16));
+ ITEM_DIFF.put(POLISHED_BLACKSTONE_PRESSURE_PLATE, andNewer(r1_16));
+ ITEM_DIFF.put(POLISHED_BLACKSTONE_BUTTON, andNewer(r1_16));
+ ITEM_DIFF.put(POLISHED_BLACKSTONE_WALL, andNewer(r1_16));
+ ITEM_DIFF.put(CHISELED_NETHER_BRICKS, andNewer(r1_16));
+ ITEM_DIFF.put(CRACKED_NETHER_BRICKS, andNewer(r1_16));
+ ITEM_DIFF.put(QUARTZ_BRICKS, andNewer(r1_16));
+ ITEM_DIFF.put(NETHERITE_SCRAP, andNewer(r1_16));
+ ITEM_DIFF.put(NETHERITE_INGOT, andNewer(r1_16));
+ ITEM_DIFF.put(NETHERITE_HELMET, andNewer(r1_16));
+ ITEM_DIFF.put(NETHERITE_CHESTPLATE, andNewer(r1_16));
+ ITEM_DIFF.put(NETHERITE_LEGGINGS, andNewer(r1_16));
+ ITEM_DIFF.put(NETHERITE_BOOTS, andNewer(r1_16));
+ ITEM_DIFF.put(NETHERITE_SWORD, andNewer(r1_16));
+ ITEM_DIFF.put(NETHERITE_SHOVEL, andNewer(r1_16));
+ ITEM_DIFF.put(NETHERITE_AXE, andNewer(r1_16));
+ ITEM_DIFF.put(NETHERITE_PICKAXE, andNewer(r1_16));
+ ITEM_DIFF.put(NETHERITE_HOE, andNewer(r1_16));
+ ITEM_DIFF.put(WARPED_FUNGUS_ON_A_STICK, andNewer(r1_16));
+ ITEM_DIFF.put(MUSIC_DISC_PIGSTEP, andNewer(r1_16));
+ ITEM_DIFF.put(PIGLIN_BANNER_PATTERN, andNewer(r1_16));
+ ITEM_DIFF.put(HOGLIN_SPAWN_EGG, andNewer(r1_16));
+ ITEM_DIFF.put(PIGLIN_SPAWN_EGG, andNewer(r1_16));
+ ITEM_DIFF.put(PIGLIN_BRUTE_SPAWN_EGG, andNewer(r1_16));
+ ITEM_DIFF.put(STRIDER_SPAWN_EGG, andNewer(r1_16));
+ ITEM_DIFF.put(ZOGLIN_SPAWN_EGG, andNewer(r1_16));
+
+ ITEM_DIFF.put(BEE_NEST, andNewer(r1_15));
+ ITEM_DIFF.put(BEEHIVE, andNewer(r1_15));
+ ITEM_DIFF.put(HONEY_BLOCK, andNewer(r1_15));
+ ITEM_DIFF.put(HONEYCOMB_BLOCK, andNewer(r1_15));
+ ITEM_DIFF.put(HONEYCOMB, andNewer(r1_15));
+ ITEM_DIFF.put(HONEY_BOTTLE, andNewer(r1_15));
+ ITEM_DIFF.put(BEE_SPAWN_EGG, andNewer(r1_15));
+
+ ITEM_DIFF.put(CORNFLOWER, andNewer(r1_14));
+ ITEM_DIFF.put(LILY_OF_THE_VALLEY, andNewer(r1_14));
+ ITEM_DIFF.put(WITHER_ROSE, andNewer(r1_14));
+ ITEM_DIFF.put(STONE_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(CUT_SANDSTONE_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(CUT_RED_SANDSTONE_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(BRICK_WALL, andNewer(r1_14));
+ ITEM_DIFF.put(PRISMARINE_WALL, andNewer(r1_14));
+ ITEM_DIFF.put(RED_SANDSTONE_WALL, andNewer(r1_14));
+ ITEM_DIFF.put(MOSSY_STONE_BRICK_WALL, andNewer(r1_14));
+ ITEM_DIFF.put(GRANITE_WALL, andNewer(r1_14));
+ ITEM_DIFF.put(STONE_BRICK_WALL, andNewer(r1_14));
+ ITEM_DIFF.put(NETHER_BRICK_WALL, andNewer(r1_14));
+ ITEM_DIFF.put(ANDESITE_WALL, andNewer(r1_14));
+ ITEM_DIFF.put(RED_NETHER_BRICK_WALL, andNewer(r1_14));
+ ITEM_DIFF.put(SANDSTONE_WALL, andNewer(r1_14));
+ ITEM_DIFF.put(END_STONE_BRICK_WALL, andNewer(r1_14));
+ ITEM_DIFF.put(DIORITE_WALL, andNewer(r1_14));
+ ITEM_DIFF.put(POLISHED_GRANITE_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(SMOOTH_RED_SANDSTONE_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(MOSSY_STONE_BRICK_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(POLISHED_DIORITE_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(MOSSY_COBBLESTONE_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(END_STONE_BRICK_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(STONE_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(SMOOTH_SANDSTONE_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(SMOOTH_QUARTZ_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(GRANITE_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(ANDESITE_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(RED_NETHER_BRICK_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(POLISHED_ANDESITE_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(DIORITE_STAIRS, andNewer(r1_14));
+ ITEM_DIFF.put(POLISHED_GRANITE_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(SMOOTH_RED_SANDSTONE_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(MOSSY_STONE_BRICK_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(POLISHED_DIORITE_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(MOSSY_COBBLESTONE_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(END_STONE_BRICK_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(SMOOTH_SANDSTONE_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(SMOOTH_QUARTZ_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(GRANITE_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(ANDESITE_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(RED_NETHER_BRICK_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(POLISHED_ANDESITE_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(DIORITE_SLAB, andNewer(r1_14));
+ ITEM_DIFF.put(SCAFFOLDING, andNewer(r1_14));
+ ITEM_DIFF.put(JIGSAW, andNewer(r1_14));
+ ITEM_DIFF.put(COMPOSTER, andNewer(r1_14));
+ ITEM_DIFF.put(SPRUCE_SIGN, andNewer(r1_14));
+ ITEM_DIFF.put(BIRCH_SIGN, andNewer(r1_14));
+ ITEM_DIFF.put(JUNGLE_SIGN, andNewer(r1_14));
+ ITEM_DIFF.put(ACACIA_SIGN, andNewer(r1_14));
+ ITEM_DIFF.put(DARK_OAK_SIGN, andNewer(r1_14));
+ ITEM_DIFF.put(BAMBOO, andNewer(r1_14));
+ ITEM_DIFF.put(BLUE_DYE, andNewer(r1_14));
+ ITEM_DIFF.put(BROWN_DYE, andNewer(r1_14));
+ ITEM_DIFF.put(BLACK_DYE, andNewer(r1_14));
+ ITEM_DIFF.put(WHITE_DYE, andNewer(r1_14));
+ ITEM_DIFF.put(CAT_SPAWN_EGG, andNewer(r1_14));
+ ITEM_DIFF.put(FOX_SPAWN_EGG, andNewer(r1_14));
+ ITEM_DIFF.put(PANDA_SPAWN_EGG, andNewer(r1_14));
+ ITEM_DIFF.put(PILLAGER_SPAWN_EGG, andNewer(r1_14));
+ ITEM_DIFF.put(RAVAGER_SPAWN_EGG, andNewer(r1_14));
+ ITEM_DIFF.put(TRADER_LLAMA_SPAWN_EGG, andNewer(r1_14));
+ ITEM_DIFF.put(WANDERING_TRADER_SPAWN_EGG, andNewer(r1_14));
+ ITEM_DIFF.put(LEATHER_HORSE_ARMOR, andNewer(r1_14));
+ ITEM_DIFF.put(CROSSBOW, andNewer(r1_14));
+ ITEM_DIFF.put(SUSPICIOUS_STEW, andNewer(r1_14));
+ ITEM_DIFF.put(LOOM, andNewer(r1_14));
+ ITEM_DIFF.put(FLOWER_BANNER_PATTERN, andNewer(r1_14));
+ ITEM_DIFF.put(CREEPER_BANNER_PATTERN, andNewer(r1_14));
+ ITEM_DIFF.put(SKULL_BANNER_PATTERN, andNewer(r1_14));
+ ITEM_DIFF.put(MOJANG_BANNER_PATTERN, andNewer(r1_14));
+ ITEM_DIFF.put(GLOBE_BANNER_PATTERN, andNewer(r1_14));
+ ITEM_DIFF.put(BARREL, andNewer(r1_14));
+ ITEM_DIFF.put(SMOKER, andNewer(r1_14));
+ ITEM_DIFF.put(BLAST_FURNACE, andNewer(r1_14));
+ ITEM_DIFF.put(CARTOGRAPHY_TABLE, andNewer(r1_14));
+ ITEM_DIFF.put(FLETCHING_TABLE, andNewer(r1_14));
+ ITEM_DIFF.put(GRINDSTONE, andNewer(r1_14));
+ ITEM_DIFF.put(LECTERN, andNewer(r1_14));
+ ITEM_DIFF.put(SMITHING_TABLE, andNewer(r1_14));
+ ITEM_DIFF.put(STONECUTTER, andNewer(r1_14));
+ ITEM_DIFF.put(BELL, andNewer(r1_14));
+ ITEM_DIFF.put(LANTERN, andNewer(r1_14));
+ ITEM_DIFF.put(SWEET_BERRIES, andNewer(r1_14));
+ ITEM_DIFF.put(CAMPFIRE, andNewer(r1_14));
+
+ ITEM_DIFF.put(DEAD_BRAIN_CORAL, andNewer(r1_13_1));
+ ITEM_DIFF.put(DEAD_BUBBLE_CORAL, andNewer(r1_13_1));
+ ITEM_DIFF.put(DEAD_FIRE_CORAL, andNewer(r1_13_1));
+ ITEM_DIFF.put(DEAD_HORN_CORAL, andNewer(r1_13_1));
+ ITEM_DIFF.put(DEAD_TUBE_CORAL, andNewer(r1_13_1));
+
+ ITEM_DIFF.put(STRIPPED_OAK_LOG, andNewer(r1_13));
+ ITEM_DIFF.put(STRIPPED_SPRUCE_LOG, andNewer(r1_13));
+ ITEM_DIFF.put(STRIPPED_BIRCH_LOG, andNewer(r1_13));
+ ITEM_DIFF.put(STRIPPED_JUNGLE_LOG, andNewer(r1_13));
+ ITEM_DIFF.put(STRIPPED_ACACIA_LOG, andNewer(r1_13));
+ ITEM_DIFF.put(STRIPPED_DARK_OAK_LOG, andNewer(r1_13));
+ ITEM_DIFF.put(STRIPPED_OAK_WOOD, andNewer(r1_13));
+ ITEM_DIFF.put(STRIPPED_SPRUCE_WOOD, andNewer(r1_13));
+ ITEM_DIFF.put(STRIPPED_BIRCH_WOOD, andNewer(r1_13));
+ ITEM_DIFF.put(STRIPPED_JUNGLE_WOOD, andNewer(r1_13));
+ ITEM_DIFF.put(STRIPPED_ACACIA_WOOD, andNewer(r1_13));
+ ITEM_DIFF.put(STRIPPED_DARK_OAK_WOOD, andNewer(r1_13));
+ ITEM_DIFF.put(OAK_WOOD, andNewer(r1_13));
+ ITEM_DIFF.put(SPRUCE_WOOD, andNewer(r1_13));
+ ITEM_DIFF.put(BIRCH_WOOD, andNewer(r1_13));
+ ITEM_DIFF.put(JUNGLE_WOOD, andNewer(r1_13));
+ ITEM_DIFF.put(ACACIA_WOOD, andNewer(r1_13));
+ ITEM_DIFF.put(DARK_OAK_WOOD, andNewer(r1_13));
+ ITEM_DIFF.put(SEAGRASS, andNewer(r1_13));
+ ITEM_DIFF.put(SEA_PICKLE, andNewer(r1_13));
+ ITEM_DIFF.put(PRISMARINE_SLAB, andNewer(r1_13));
+ ITEM_DIFF.put(PRISMARINE_BRICK_SLAB, andNewer(r1_13));
+ ITEM_DIFF.put(DARK_PRISMARINE_SLAB, andNewer(r1_13));
+ ITEM_DIFF.put(SMOOTH_QUARTZ, andNewer(r1_13));
+ ITEM_DIFF.put(SMOOTH_RED_SANDSTONE, andNewer(r1_13));
+ ITEM_DIFF.put(SMOOTH_SANDSTONE, andNewer(r1_13));
+ ITEM_DIFF.put(SMOOTH_STONE, andNewer(r1_13));
+ ITEM_DIFF.put(SPRUCE_PRESSURE_PLATE, andNewer(r1_13));
+ ITEM_DIFF.put(BIRCH_PRESSURE_PLATE, andNewer(r1_13));
+ ITEM_DIFF.put(JUNGLE_PRESSURE_PLATE, andNewer(r1_13));
+ ITEM_DIFF.put(ACACIA_PRESSURE_PLATE, andNewer(r1_13));
+ ITEM_DIFF.put(DARK_OAK_PRESSURE_PLATE, andNewer(r1_13));
+ ITEM_DIFF.put(PUMPKIN, andNewer(r1_13));
+ ITEM_DIFF.put(SPRUCE_TRAPDOOR, andNewer(r1_13));
+ ITEM_DIFF.put(BIRCH_TRAPDOOR, andNewer(r1_13));
+ ITEM_DIFF.put(JUNGLE_TRAPDOOR, andNewer(r1_13));
+ ITEM_DIFF.put(ACACIA_TRAPDOOR, andNewer(r1_13));
+ ITEM_DIFF.put(DARK_OAK_TRAPDOOR, andNewer(r1_13));
+ ITEM_DIFF.put(SPRUCE_BUTTON, andNewer(r1_13));
+ ITEM_DIFF.put(BIRCH_BUTTON, andNewer(r1_13));
+ ITEM_DIFF.put(JUNGLE_BUTTON, andNewer(r1_13));
+ ITEM_DIFF.put(ACACIA_BUTTON, andNewer(r1_13));
+ ITEM_DIFF.put(DARK_OAK_BUTTON, andNewer(r1_13));
+ ITEM_DIFF.put(PRISMARINE_STAIRS, andNewer(r1_13));
+ ITEM_DIFF.put(PRISMARINE_BRICK_STAIRS, andNewer(r1_13));
+ ITEM_DIFF.put(DARK_PRISMARINE_STAIRS, andNewer(r1_13));
+ ITEM_DIFF.put(SHULKER_BOX, andNewer(r1_13));
+ ITEM_DIFF.put(TURTLE_EGG, andNewer(r1_13));
+ ITEM_DIFF.put(DEAD_TUBE_CORAL_BLOCK, andNewer(r1_13));
+ ITEM_DIFF.put(DEAD_BRAIN_CORAL_BLOCK, andNewer(r1_13));
+ ITEM_DIFF.put(DEAD_BUBBLE_CORAL_BLOCK, andNewer(r1_13));
+ ITEM_DIFF.put(DEAD_FIRE_CORAL_BLOCK, andNewer(r1_13));
+ ITEM_DIFF.put(DEAD_HORN_CORAL_BLOCK, andNewer(r1_13));
+ ITEM_DIFF.put(TUBE_CORAL_BLOCK, andNewer(r1_13));
+ ITEM_DIFF.put(BRAIN_CORAL_BLOCK, andNewer(r1_13));
+ ITEM_DIFF.put(BUBBLE_CORAL_BLOCK, andNewer(r1_13));
+ ITEM_DIFF.put(FIRE_CORAL_BLOCK, andNewer(r1_13));
+ ITEM_DIFF.put(HORN_CORAL_BLOCK, andNewer(r1_13));
+ ITEM_DIFF.put(TUBE_CORAL, andNewer(r1_13));
+ ITEM_DIFF.put(BRAIN_CORAL, andNewer(r1_13));
+ ITEM_DIFF.put(BUBBLE_CORAL, andNewer(r1_13));
+ ITEM_DIFF.put(FIRE_CORAL, andNewer(r1_13));
+ ITEM_DIFF.put(HORN_CORAL, andNewer(r1_13));
+ ITEM_DIFF.put(TUBE_CORAL_FAN, andNewer(r1_13));
+ ITEM_DIFF.put(BRAIN_CORAL_FAN, andNewer(r1_13));
+ ITEM_DIFF.put(BUBBLE_CORAL_FAN, andNewer(r1_13));
+ ITEM_DIFF.put(FIRE_CORAL_FAN, andNewer(r1_13));
+ ITEM_DIFF.put(HORN_CORAL_FAN, andNewer(r1_13));
+ ITEM_DIFF.put(DEAD_TUBE_CORAL_FAN, andNewer(r1_13));
+ ITEM_DIFF.put(DEAD_BRAIN_CORAL_FAN, andNewer(r1_13));
+ ITEM_DIFF.put(DEAD_BUBBLE_CORAL_FAN, andNewer(r1_13));
+ ITEM_DIFF.put(DEAD_FIRE_CORAL_FAN, andNewer(r1_13));
+ ITEM_DIFF.put(DEAD_HORN_CORAL_FAN, andNewer(r1_13));
+ ITEM_DIFF.put(BLUE_ICE, andNewer(r1_13));
+ ITEM_DIFF.put(CONDUIT, andNewer(r1_13));
+ ITEM_DIFF.put(TURTLE_HELMET, andNewer(r1_13));
+ ITEM_DIFF.put(SCUTE, andNewer(r1_13));
+ ITEM_DIFF.put(PUFFERFISH_BUCKET, andNewer(r1_13));
+ ITEM_DIFF.put(SALMON_BUCKET, andNewer(r1_13));
+ ITEM_DIFF.put(COD_BUCKET, andNewer(r1_13));
+ ITEM_DIFF.put(TROPICAL_FISH_BUCKET, andNewer(r1_13));
+ ITEM_DIFF.put(KELP, andNewer(r1_13));
+ ITEM_DIFF.put(DRIED_KELP_BLOCK, andNewer(r1_13));
+ ITEM_DIFF.put(DRIED_KELP, andNewer(r1_13));
+ ITEM_DIFF.put(COD_SPAWN_EGG, andNewer(r1_13));
+ ITEM_DIFF.put(DOLPHIN_SPAWN_EGG, andNewer(r1_13));
+ ITEM_DIFF.put(DROWNED_SPAWN_EGG, andNewer(r1_13));
+ ITEM_DIFF.put(PHANTOM_SPAWN_EGG, andNewer(r1_13));
+ ITEM_DIFF.put(PUFFERFISH_SPAWN_EGG, andNewer(r1_13));
+ ITEM_DIFF.put(SALMON_SPAWN_EGG, andNewer(r1_13));
+ ITEM_DIFF.put(TROPICAL_FISH_SPAWN_EGG, andNewer(r1_13));
+ ITEM_DIFF.put(TURTLE_SPAWN_EGG, andNewer(r1_13));
+ ITEM_DIFF.put(DEBUG_STICK, andNewer(r1_13));
+ ITEM_DIFF.put(TRIDENT, andNewer(r1_13));
+ ITEM_DIFF.put(PHANTOM_MEMBRANE, andNewer(r1_13));
+ ITEM_DIFF.put(NAUTILUS_SHELL, andNewer(r1_13));
+ ITEM_DIFF.put(HEART_OF_THE_SEA, andNewer(r1_13));
+
+ ITEM_DIFF.put(KNOWLEDGE_BOOK, andNewer(r1_12));
+ ITEM_DIFF.put(WHITE_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(ORANGE_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(MAGENTA_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(LIGHT_BLUE_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(YELLOW_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(LIME_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(PINK_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(GRAY_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(LIGHT_GRAY_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(CYAN_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(PURPLE_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(BLUE_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(BROWN_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(GREEN_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(RED_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(BLACK_GLAZED_TERRACOTTA, andNewer(r1_12));
+ ITEM_DIFF.put(WHITE_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(ORANGE_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(MAGENTA_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(LIGHT_BLUE_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(YELLOW_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(LIME_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(PINK_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(GRAY_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(LIGHT_GRAY_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(CYAN_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(PURPLE_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(BLUE_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(BROWN_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(GREEN_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(RED_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(BLACK_CONCRETE, andNewer(r1_12));
+ ITEM_DIFF.put(WHITE_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(ORANGE_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(MAGENTA_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(LIGHT_BLUE_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(YELLOW_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(LIME_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(PINK_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(GRAY_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(LIGHT_GRAY_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(CYAN_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(PURPLE_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(BLUE_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(BROWN_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(GREEN_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(RED_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(BLACK_CONCRETE_POWDER, andNewer(r1_12));
+ ITEM_DIFF.put(WHITE_BED, andNewer(r1_12));
+ ITEM_DIFF.put(ORANGE_BED, andNewer(r1_12));
+ ITEM_DIFF.put(MAGENTA_BED, andNewer(r1_12));
+ ITEM_DIFF.put(LIGHT_BLUE_BED, andNewer(r1_12));
+ ITEM_DIFF.put(YELLOW_BED, andNewer(r1_12));
+ ITEM_DIFF.put(LIME_BED, andNewer(r1_12));
+ ITEM_DIFF.put(PINK_BED, andNewer(r1_12));
+ ITEM_DIFF.put(GRAY_BED, andNewer(r1_12));
+ ITEM_DIFF.put(LIGHT_GRAY_BED, andNewer(r1_12));
+ ITEM_DIFF.put(CYAN_BED, andNewer(r1_12));
+ ITEM_DIFF.put(PURPLE_BED, andNewer(r1_12));
+ ITEM_DIFF.put(BLUE_BED, andNewer(r1_12));
+ ITEM_DIFF.put(BROWN_BED, andNewer(r1_12));
+ ITEM_DIFF.put(GREEN_BED, andNewer(r1_12));
+ ITEM_DIFF.put(BLACK_BED, andNewer(r1_12));
+ ITEM_DIFF.put(PARROT_SPAWN_EGG, andNewer(r1_12));
+
+ ITEM_DIFF.put(IRON_NUGGET, andNewer(r1_11_1to1_11_2));
+
+ ITEM_DIFF.put(OBSERVER, andNewer(r1_11));
+ ITEM_DIFF.put(WHITE_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(ORANGE_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(MAGENTA_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(LIGHT_BLUE_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(YELLOW_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(LIME_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(PINK_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(GRAY_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(LIGHT_GRAY_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(CYAN_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(PURPLE_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(BLUE_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(BROWN_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(GREEN_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(RED_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(BLACK_SHULKER_BOX, andNewer(r1_11));
+ ITEM_DIFF.put(TOTEM_OF_UNDYING, andNewer(r1_11));
+ ITEM_DIFF.put(SHULKER_SHELL, andNewer(r1_11));
+ ITEM_DIFF.put(VEX_SPAWN_EGG, andNewer(r1_11));
+ ITEM_DIFF.put(POLAR_BEAR_SPAWN_EGG, andNewer(r1_11));
+ ITEM_DIFF.put(STRAY_SPAWN_EGG, andNewer(r1_11));
+ ITEM_DIFF.put(HUSK_SPAWN_EGG, andNewer(r1_11));
+ ITEM_DIFF.put(ELDER_GUARDIAN_SPAWN_EGG, andNewer(r1_11));
+ ITEM_DIFF.put(WITHER_SKELETON_SPAWN_EGG, andNewer(r1_11));
+ ITEM_DIFF.put(DONKEY_SPAWN_EGG, andNewer(r1_11));
+ ITEM_DIFF.put(MULE_SPAWN_EGG, andNewer(r1_11));
+ ITEM_DIFF.put(SKELETON_HORSE_SPAWN_EGG, andNewer(r1_11));
+ ITEM_DIFF.put(ZOMBIE_HORSE_SPAWN_EGG, andNewer(r1_11));
+ ITEM_DIFF.put(ZOMBIE_VILLAGER_SPAWN_EGG, andNewer(r1_11));
+ ITEM_DIFF.put(EVOKER_SPAWN_EGG, andNewer(r1_11));
+ ITEM_DIFF.put(LLAMA_SPAWN_EGG, andNewer(r1_11));
+ ITEM_DIFF.put(VINDICATOR_SPAWN_EGG, andNewer(r1_11));
+
+ ITEM_DIFF.put(MAGMA_BLOCK, andNewer(r1_10));
+ ITEM_DIFF.put(NETHER_WART_BLOCK, andNewer(r1_10));
+ ITEM_DIFF.put(RED_NETHER_BRICKS, andNewer(r1_10));
+ ITEM_DIFF.put(BONE_BLOCK, andNewer(r1_10));
+ ITEM_DIFF.put(STRUCTURE_VOID, andNewer(r1_10));
+ ITEM_DIFF.put(STRUCTURE_BLOCK, andNewer(r1_10));
+
+ ITEM_DIFF.put(END_ROD, andNewer(r1_9));
+ ITEM_DIFF.put(CHORUS_PLANT, andNewer(r1_9));
+ ITEM_DIFF.put(CHORUS_FLOWER, andNewer(r1_9));
+ ITEM_DIFF.put(PURPUR_BLOCK, andNewer(r1_9));
+ ITEM_DIFF.put(PURPUR_PILLAR, andNewer(r1_9));
+ ITEM_DIFF.put(PURPUR_STAIRS, andNewer(r1_9));
+ ITEM_DIFF.put(PURPUR_SLAB, andNewer(r1_9));
+ ITEM_DIFF.put(END_STONE_BRICKS, andNewer(r1_9));
+ ITEM_DIFF.put(DIRT_PATH, andNewer(r1_9));
+ ITEM_DIFF.put(REPEATING_COMMAND_BLOCK, andNewer(r1_9));
+ ITEM_DIFF.put(CHAIN_COMMAND_BLOCK, andNewer(r1_9));
+ ITEM_DIFF.put(END_CRYSTAL, andNewer(r1_9));
+ ITEM_DIFF.put(CHORUS_FRUIT, andNewer(r1_9));
+ ITEM_DIFF.put(POPPED_CHORUS_FRUIT, andNewer(r1_9));
+ ITEM_DIFF.put(BEETROOT, andNewer(r1_9));
+ ITEM_DIFF.put(BEETROOT_SEEDS, andNewer(r1_9));
+ ITEM_DIFF.put(BEETROOT_SOUP, andNewer(r1_9));
+ ITEM_DIFF.put(DRAGON_HEAD, andNewer(r1_9));
+ ITEM_DIFF.put(DRAGON_BREATH, andNewer(r1_9));
+ ITEM_DIFF.put(SPECTRAL_ARROW, andNewer(r1_9));
+ ITEM_DIFF.put(TIPPED_ARROW, andNewer(r1_9));
+ ITEM_DIFF.put(SPRUCE_BOAT, andNewer(r1_9));
+ ITEM_DIFF.put(BIRCH_BOAT, andNewer(r1_9));
+ ITEM_DIFF.put(JUNGLE_BOAT, andNewer(r1_9));
+ ITEM_DIFF.put(ACACIA_BOAT, andNewer(r1_9));
+ ITEM_DIFF.put(DARK_OAK_BOAT, andNewer(r1_9));
+ ITEM_DIFF.put(LINGERING_POTION, andNewer(r1_9));
+ ITEM_DIFF.put(SHIELD, andNewer(r1_9));
+ ITEM_DIFF.put(ELYTRA, andNewer(r1_9));
+ ITEM_DIFF.put(SHULKER_SPAWN_EGG, andNewer(r1_9));
+
+ ITEM_DIFF.put(ACACIA_DOOR, andNewer(r1_8));
+ ITEM_DIFF.put(ACACIA_FENCE, andNewer(r1_8));
+ ITEM_DIFF.put(ACACIA_FENCE_GATE, andNewer(r1_8));
+ ITEM_DIFF.put(ARMOR_STAND, andNewer(r1_8));
+ ITEM_DIFF.put(WHITE_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(ORANGE_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(MAGENTA_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(LIGHT_BLUE_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(YELLOW_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(LIME_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(PINK_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(GRAY_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(LIGHT_GRAY_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(CYAN_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(PURPLE_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(BLUE_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(BROWN_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(GREEN_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(RED_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(BLACK_BANNER, andNewer(r1_8));
+ ITEM_DIFF.put(BARRIER, andNewer(r1_8));
+ ITEM_DIFF.put(BIRCH_DOOR, andNewer(r1_8));
+ ITEM_DIFF.put(BIRCH_FENCE, andNewer(r1_8));
+ ITEM_DIFF.put(BIRCH_FENCE_GATE, andNewer(r1_8));
+ ITEM_DIFF.put(COOKED_MUTTON, andNewer(r1_8));
+ ITEM_DIFF.put(COOKED_RABBIT, andNewer(r1_8));
+ ITEM_DIFF.put(DARK_OAK_DOOR, andNewer(r1_8));
+ ITEM_DIFF.put(DARK_OAK_FENCE, andNewer(r1_8));
+ ITEM_DIFF.put(DARK_OAK_FENCE_GATE, andNewer(r1_8));
+ ITEM_DIFF.put(IRON_TRAPDOOR, andNewer(r1_8));
+ ITEM_DIFF.put(JUNGLE_DOOR, andNewer(r1_8));
+ ITEM_DIFF.put(JUNGLE_FENCE, andNewer(r1_8));
+ ITEM_DIFF.put(JUNGLE_FENCE_GATE, andNewer(r1_8));
+ ITEM_DIFF.put(MUTTON, andNewer(r1_8));
+ ITEM_DIFF.put(PRISMARINE, andNewer(r1_8));
+ ITEM_DIFF.put(PRISMARINE_CRYSTALS, andNewer(r1_8));
+ ITEM_DIFF.put(PRISMARINE_SHARD, andNewer(r1_8));
+ ITEM_DIFF.put(RABBIT, andNewer(r1_8));
+ ITEM_DIFF.put(RABBIT_FOOT, andNewer(r1_8));
+ ITEM_DIFF.put(RABBIT_HIDE, andNewer(r1_8));
+ ITEM_DIFF.put(RABBIT_STEW, andNewer(r1_8));
+ ITEM_DIFF.put(RED_SANDSTONE, andNewer(r1_8));
+ ITEM_DIFF.put(RED_SANDSTONE_STAIRS, andNewer(r1_8));
+ ITEM_DIFF.put(CUT_RED_SANDSTONE, andNewer(r1_8));
+ ITEM_DIFF.put(CHISELED_RED_SANDSTONE, andNewer(r1_8));
+ ITEM_DIFF.put(RED_SANDSTONE_SLAB, andNewer(r1_8));
+ ITEM_DIFF.put(SEA_LANTERN, andNewer(r1_8));
+ ITEM_DIFF.put(SLIME_BLOCK, andNewer(r1_8));
+ ITEM_DIFF.put(SPRUCE_DOOR, andNewer(r1_8));
+ ITEM_DIFF.put(SPRUCE_FENCE, andNewer(r1_8));
+ ITEM_DIFF.put(SPRUCE_FENCE_GATE, andNewer(r1_8));
+ ITEM_DIFF.put(DIORITE, andNewer(r1_8));
+ ITEM_DIFF.put(POLISHED_DIORITE, andNewer(r1_8));
+ ITEM_DIFF.put(ANDESITE, andNewer(r1_8));
+ ITEM_DIFF.put(POLISHED_ANDESITE, andNewer(r1_8));
+ ITEM_DIFF.put(GRANITE, andNewer(r1_8));
+ ITEM_DIFF.put(POLISHED_GRANITE, andNewer(r1_8));
+ ITEM_DIFF.put(DARK_PRISMARINE, andNewer(r1_8));
+ ITEM_DIFF.put(PRISMARINE_BRICKS, andNewer(r1_8));
+ ITEM_DIFF.put(WET_SPONGE, andNewer(r1_8));
+ ITEM_DIFF.put(COARSE_DIRT, andNewer(r1_8));
+ ITEM_DIFF.put(RABBIT_SPAWN_EGG, andNewer(r1_8));
+ ITEM_DIFF.put(GUARDIAN_SPAWN_EGG, andNewer(r1_8));
+ ITEM_DIFF.put(ENDERMITE_SPAWN_EGG, andNewer(r1_8));
+
+ ITEM_DIFF.put(WHITE_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(ORANGE_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(MAGENTA_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(LIGHT_BLUE_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(YELLOW_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(LIME_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(PINK_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(GRAY_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(LIGHT_GRAY_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(CYAN_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(PURPLE_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(BLUE_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(BROWN_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(GREEN_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(RED_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(BLACK_STAINED_GLASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(WHITE_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(ORANGE_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(MAGENTA_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(LIGHT_BLUE_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(YELLOW_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(LIME_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(PINK_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(GRAY_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(LIGHT_GRAY_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(CYAN_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(PURPLE_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(BLUE_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(BROWN_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(GREEN_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(RED_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(BLACK_STAINED_GLASS_PANE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(ACACIA_LOG, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(DARK_OAK_LOG, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(ACACIA_PLANKS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(DARK_OAK_PLANKS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(ACACIA_SLAB, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(DARK_OAK_SLAB, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(ACACIA_STAIRS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(DARK_OAK_STAIRS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(ACACIA_SAPLING, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(DARK_OAK_SAPLING, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(ACACIA_LEAVES, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(DARK_OAK_LEAVES, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(PACKED_ICE, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(PODZOL, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(RED_SAND, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(RED_TULIP, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(ORANGE_TULIP, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(WHITE_TULIP, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(PINK_TULIP, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(BLUE_ORCHID, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(ALLIUM, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(AZURE_BLUET, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(OXEYE_DAISY, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(SUNFLOWER, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(PEONY, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(ROSE_BUSH, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(LILAC, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(TALL_GRASS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(LARGE_FERN, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(INFESTED_MOSSY_STONE_BRICKS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(INFESTED_CRACKED_STONE_BRICKS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(INFESTED_CHISELED_STONE_BRICKS, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(PUFFERFISH, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(SALMON, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(COOKED_SALMON, andNewer(r1_7_2tor1_7_5));
+ ITEM_DIFF.put(TROPICAL_FISH, andNewer(r1_7_2tor1_7_5));
+
+ ITEM_DIFF.put(HAY_BLOCK, andNewer(r1_6_1));
+ ITEM_DIFF.put(WHITE_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(ORANGE_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(MAGENTA_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(LIGHT_BLUE_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(YELLOW_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(LIME_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(PINK_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(GRAY_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(LIGHT_GRAY_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(CYAN_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(PURPLE_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(BLUE_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(BROWN_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(GREEN_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(RED_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(BLACK_CARPET, andNewer(r1_6_1));
+ ITEM_DIFF.put(TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(WHITE_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(ORANGE_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(MAGENTA_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(LIGHT_BLUE_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(YELLOW_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(LIME_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(PINK_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(GRAY_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(LIGHT_GRAY_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(CYAN_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(PURPLE_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(BLUE_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(BROWN_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(GREEN_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(RED_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(BLACK_TERRACOTTA, andNewer(r1_6_1));
+ ITEM_DIFF.put(COAL_BLOCK, andNewer(r1_6_1));
+ ITEM_DIFF.put(IRON_HORSE_ARMOR, andNewer(r1_6_1));
+ ITEM_DIFF.put(GOLDEN_HORSE_ARMOR, andNewer(r1_6_1));
+ ITEM_DIFF.put(DIAMOND_HORSE_ARMOR, andNewer(r1_6_1));
+ ITEM_DIFF.put(HORSE_SPAWN_EGG, andNewer(r1_6_1));
+ ITEM_DIFF.put(LEAD, andNewer(r1_6_1));
+ ITEM_DIFF.put(NAME_TAG, andNewer(r1_6_1));
+
+ ITEM_DIFF.put(ACTIVATOR_RAIL, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(REDSTONE_BLOCK, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(DAYLIGHT_DETECTOR, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(DROPPER, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(HOPPER, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(COMPARATOR, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(TRAPPED_CHEST, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(LIGHT_WEIGHTED_PRESSURE_PLATE, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(HEAVY_WEIGHTED_PRESSURE_PLATE, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(NETHER_QUARTZ_ORE, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(QUARTZ_BLOCK, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(QUARTZ_SLAB, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(QUARTZ_STAIRS, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(CHISELED_QUARTZ_BLOCK, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(QUARTZ_PILLAR, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(NETHER_BRICK, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(QUARTZ, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(TNT_MINECART, andNewer(r1_5tor1_5_1));
+ ITEM_DIFF.put(HOPPER_MINECART, andNewer(r1_5tor1_5_1));
+
+ ITEM_DIFF.put(NETHER_BRICK_SLAB, andNewer(r1_4_6tor1_4_7));
+ ITEM_DIFF.put(ENCHANTED_BOOK, andNewer(r1_4_6tor1_4_7));
+ ITEM_DIFF.put(FIREWORK_STAR, andNewer(r1_4_6tor1_4_7));
+ ITEM_DIFF.put(FIREWORK_ROCKET, andNewer(r1_4_6tor1_4_7));
+
+ ITEM_DIFF.put(MUSIC_DISC_WAIT, andNewer(r1_4_4tor1_4_5));
+
+ ITEM_DIFF.put(COMMAND_BLOCK, andNewer(r1_4_2));
+ ITEM_DIFF.put(COMMAND_BLOCK_MINECART, andNewer(r1_4_2));
+ ITEM_DIFF.put(BEACON, andNewer(r1_4_2));
+ ITEM_DIFF.put(ANVIL, andNewer(r1_4_2));
+ ITEM_DIFF.put(CHIPPED_ANVIL, andNewer(r1_4_2));
+ ITEM_DIFF.put(DAMAGED_ANVIL, andNewer(r1_4_2));
+ ITEM_DIFF.put(FLOWER_POT, andNewer(r1_4_2));
+ ITEM_DIFF.put(COBBLESTONE_WALL, andNewer(r1_4_2));
+ ITEM_DIFF.put(MOSSY_COBBLESTONE_WALL, andNewer(r1_4_2));
+ ITEM_DIFF.put(CREEPER_HEAD, andNewer(r1_4_2));
+ ITEM_DIFF.put(ZOMBIE_HEAD, andNewer(r1_4_2));
+ ITEM_DIFF.put(SKELETON_SKULL, andNewer(r1_4_2));
+ ITEM_DIFF.put(WITHER_SKELETON_SKULL, andNewer(r1_4_2));
+ ITEM_DIFF.put(PLAYER_HEAD, andNewer(r1_4_2));
+ ITEM_DIFF.put(OAK_BUTTON, andNewer(r1_4_2));
+ ITEM_DIFF.put(POTATO, andNewer(r1_4_2));
+ ITEM_DIFF.put(POISONOUS_POTATO, andNewer(r1_4_2));
+ ITEM_DIFF.put(BAKED_POTATO, andNewer(r1_4_2));
+ ITEM_DIFF.put(CARROT, andNewer(r1_4_2));
+ ITEM_DIFF.put(GOLDEN_CARROT, andNewer(r1_4_2));
+ ITEM_DIFF.put(CARROT_ON_A_STICK, andNewer(r1_4_2));
+ ITEM_DIFF.put(PUMPKIN_PIE, andNewer(r1_4_2));
+ ITEM_DIFF.put(NETHER_STAR, andNewer(r1_4_2));
+ ITEM_DIFF.put(BAT_SPAWN_EGG, andNewer(r1_4_2));
+ ITEM_DIFF.put(WITCH_SPAWN_EGG, andNewer(r1_4_2));
+ ITEM_DIFF.put(ITEM_FRAME, andNewer(r1_4_2));
+
+ ITEM_DIFF.put(EMERALD_ORE, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(EMERALD_BLOCK, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(EMERALD, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(ENDER_CHEST, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(TRIPWIRE_HOOK, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(SANDSTONE_STAIRS, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(WRITABLE_BOOK, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(WRITTEN_BOOK, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(ENCHANTED_GOLDEN_APPLE, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(OAK_SLAB, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(SPRUCE_SLAB, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(BIRCH_SLAB, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(JUNGLE_SLAB, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(SPRUCE_STAIRS, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(BIRCH_STAIRS, andNewer(r1_3_1tor1_3_2));
+ ITEM_DIFF.put(JUNGLE_STAIRS, andNewer(r1_3_1tor1_3_2));
+
+ ITEM_DIFF.put(BIRCH_PLANKS, andNewer(r1_2_4tor1_2_5));
+ ITEM_DIFF.put(SPRUCE_PLANKS, andNewer(r1_2_4tor1_2_5));
+ ITEM_DIFF.put(JUNGLE_PLANKS, andNewer(r1_2_4tor1_2_5));
+ ITEM_DIFF.put(CHISELED_SANDSTONE, andNewer(r1_2_4tor1_2_5));
+ ITEM_DIFF.put(CUT_SANDSTONE, andNewer(r1_2_4tor1_2_5));
+
+ ITEM_DIFF.put(CHISELED_STONE_BRICKS, andNewer(r1_2_1tor1_2_3));
+ ITEM_DIFF.put(REDSTONE_LAMP, andNewer(r1_2_1tor1_2_3));
+ ITEM_DIFF.put(JUNGLE_LOG, andNewer(r1_2_1tor1_2_3));
+ ITEM_DIFF.put(JUNGLE_LEAVES, andNewer(r1_2_1tor1_2_3));
+ ITEM_DIFF.put(JUNGLE_SAPLING, andNewer(r1_2_1tor1_2_3));
+ ITEM_DIFF.put(EXPERIENCE_BOTTLE, andNewer(r1_2_1tor1_2_3));
+ ITEM_DIFF.put(FIRE_CHARGE, andNewer(r1_2_1tor1_2_3));
+ ITEM_DIFF.put(OCELOT_SPAWN_EGG, andNewer(r1_2_1tor1_2_3));
+
+ ITEM_DIFF.put(BLAZE_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(CAVE_SPIDER_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(CHICKEN_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(COW_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(CREEPER_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(ENDERMAN_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(GHAST_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(MAGMA_CUBE_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(MOOSHROOM_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(PIG_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(SHEEP_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(SILVERFISH_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(SKELETON_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(SLIME_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(SPIDER_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(SQUID_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(VILLAGER_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(WOLF_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(ZOMBIE_SPAWN_EGG, andNewer(r1_1));
+ ITEM_DIFF.put(ZOMBIFIED_PIGLIN_SPAWN_EGG, andNewer(r1_1));
+
+ ITEM_DIFF.put(BREWING_STAND, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(CAULDRON, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(DRAGON_EGG, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(ENCHANTING_TABLE, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(END_PORTAL_FRAME, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(END_STONE, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(LILY_PAD, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(MYCELIUM, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(NETHER_BRICKS, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(NETHER_BRICK_FENCE, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(NETHER_BRICK_STAIRS, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(NETHER_WART, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(BLAZE_POWDER, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(BLAZE_ROD, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(ENDER_EYE, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(SPIDER_EYE, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(FERMENTED_SPIDER_EYE, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(GHAST_TEAR, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(GLASS_BOTTLE, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(GLISTERING_MELON_SLICE, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(GOLD_NUGGET, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(MAGMA_CREAM, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(MUSIC_DISC_13, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(MUSIC_DISC_CAT, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(MUSIC_DISC_BLOCKS, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(MUSIC_DISC_CHIRP, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(MUSIC_DISC_FAR, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(MUSIC_DISC_MALL, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(MUSIC_DISC_MELLOHI, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(MUSIC_DISC_STAL, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(MUSIC_DISC_STRAD, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(MUSIC_DISC_WARD, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(MUSIC_DISC_11, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(POTION, andNewer(r1_0_0tor1_0_1));
+ ITEM_DIFF.put(SPLASH_POTION, andNewer(r1_0_0tor1_0_1));
+
+ ITEM_DIFF.put(STONE_BRICKS, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(MOSSY_STONE_BRICKS, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(CRACKED_STONE_BRICKS, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(INFESTED_STONE, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(INFESTED_STONE_BRICKS, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(INFESTED_COBBLESTONE, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(BRICK_SLAB, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(STONE_BRICK_SLAB, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(MUSHROOM_STEM, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(BROWN_MUSHROOM_BLOCK, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(RED_MUSHROOM_BLOCK, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(MELON, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(VINE, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(IRON_BARS, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(GLASS_PANE, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(OAK_FENCE_GATE, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(BRICK_STAIRS, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(STONE_BRICK_STAIRS, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(CHICKEN, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(COOKED_CHICKEN, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(BEEF, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(COOKED_BEEF, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(ENDER_PEARL, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(MELON_SEEDS, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(MELON_SLICE, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(PUMPKIN_SEEDS, andNewer(b1_8tob1_8_1));
+ ITEM_DIFF.put(ROTTEN_FLESH, andNewer(b1_8tob1_8_1));
+
+ ITEM_DIFF.put(PISTON, andNewer(b1_7tob1_7_3));
+ ITEM_DIFF.put(STICKY_PISTON, andNewer(b1_7tob1_7_3));
+ ITEM_DIFF.put(SHEARS, andNewer(b1_7tob1_7_3));
+
+ ITEM_DIFF.put(DEAD_BUSH, andNewer(b1_6tob1_6_6));
+ ITEM_DIFF.put(GRASS, andNewer(b1_6tob1_6_6));
+ ITEM_DIFF.put(FERN, andNewer(b1_6tob1_6_6));
+ ITEM_DIFF.put(OAK_TRAPDOOR, andNewer(b1_6tob1_6_6));
+ ITEM_DIFF.put(MAP, andNewer(b1_6tob1_6_6));
+ ITEM_DIFF.put(FILLED_MAP, andNewer(b1_6tob1_6_6));
+
+ ITEM_DIFF.put(BIRCH_SAPLING, andNewer(b1_5tob1_5_2));
+ ITEM_DIFF.put(COBWEB, andNewer(b1_5tob1_5_2));
+ ITEM_DIFF.put(DETECTOR_RAIL, andNewer(b1_5tob1_5_2));
+ ITEM_DIFF.put(POWERED_RAIL, andNewer(b1_5tob1_5_2));
+ ITEM_DIFF.put(SPRUCE_SAPLING, andNewer(b1_5tob1_5_2));
+
+ ITEM_DIFF.put(COOKIE, andNewer(b1_4tob1_4_1));
+
+ ITEM_DIFF.put(RED_BED, andNewer(b1_3tob1_3_1));
+ ITEM_DIFF.put(REPEATER, andNewer(b1_3tob1_3_1));
+ ITEM_DIFF.put(COBBLESTONE_SLAB, andNewer(b1_3tob1_3_1));
+ ITEM_DIFF.put(PETRIFIED_OAK_SLAB, andNewer(b1_3tob1_3_1));
+ ITEM_DIFF.put(SANDSTONE_SLAB, andNewer(b1_3tob1_3_1));
+ ITEM_DIFF.put(PAINTING, andNewer(b1_3tob1_3_1));
+
+ ITEM_DIFF.put(CAKE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(DISPENSER, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(LAPIS_LAZULI, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(LAPIS_ORE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(LAPIS_BLOCK, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(NOTE_BLOCK, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(SANDSTONE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(SPRUCE_LOG, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(BIRCH_LOG, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(SPRUCE_LEAVES, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(BIRCH_LEAVES, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(BONE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(BONE_MEAL, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(COCOA_BEANS, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(INK_SAC, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(CHARCOAL, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(SUGAR, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(PURPLE_DYE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(CYAN_DYE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(LIGHT_GRAY_DYE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(GRAY_DYE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(PINK_DYE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(LIME_DYE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(YELLOW_DYE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(LIGHT_BLUE_DYE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(MAGENTA_DYE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(ORANGE_DYE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(RED_DYE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(GREEN_DYE, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(ORANGE_WOOL, andNewer(b1_2_0tob1_2_2).add(of(c0_0_20ac0_27, c0_28toc0_30)));
+ ITEM_DIFF.put(MAGENTA_WOOL, andNewer(b1_2_0tob1_2_2).add(of(c0_0_20ac0_27, c0_28toc0_30)));
+ ITEM_DIFF.put(LIGHT_BLUE_WOOL, andNewer(b1_2_0tob1_2_2).add(of(c0_0_20ac0_27, c0_28toc0_30)));
+ ITEM_DIFF.put(YELLOW_WOOL, andNewer(b1_2_0tob1_2_2).add(of(c0_0_20ac0_27, c0_28toc0_30)));
+ ITEM_DIFF.put(LIME_WOOL, andNewer(b1_2_0tob1_2_2).add(of(c0_0_20ac0_27, c0_28toc0_30)));
+ ITEM_DIFF.put(PINK_WOOL, andNewer(b1_2_0tob1_2_2).add(of(c0_0_20ac0_27, c0_28toc0_30)));
+ ITEM_DIFF.put(GRAY_WOOL, andNewer(b1_2_0tob1_2_2).add(of(c0_0_20ac0_27, c0_28toc0_30)));
+ ITEM_DIFF.put(LIGHT_GRAY_WOOL, andNewer(b1_2_0tob1_2_2).add(of(c0_0_20ac0_27, c0_28toc0_30)));
+ ITEM_DIFF.put(CYAN_WOOL, andNewer(b1_2_0tob1_2_2).add(of(c0_0_20ac0_27, c0_28toc0_30)));
+ ITEM_DIFF.put(PURPLE_WOOL, andNewer(b1_2_0tob1_2_2).add(of(c0_0_20ac0_27, c0_28toc0_30)));
+ ITEM_DIFF.put(BLUE_WOOL, andNewer(b1_2_0tob1_2_2).add(of(c0_0_20ac0_27, c0_28toc0_30)));
+ ITEM_DIFF.put(BROWN_WOOL, andNewer(b1_2_0tob1_2_2));
+ ITEM_DIFF.put(GREEN_WOOL, andNewer(b1_2_0tob1_2_2).add(of(c0_0_20ac0_27, c0_28toc0_30)));
+ ITEM_DIFF.put(RED_WOOL, andNewer(b1_2_0tob1_2_2).add(of(c0_0_20ac0_27, c0_28toc0_30)));
+ ITEM_DIFF.put(BLACK_WOOL, andNewer(b1_2_0tob1_2_2));
+
+ ITEM_DIFF.put(JACK_O_LANTERN, andNewer(a1_2_0toa1_2_1_1));
+ ITEM_DIFF.put(GLOWSTONE, andNewer(a1_2_0toa1_2_1_1));
+ ITEM_DIFF.put(CLOCK, andNewer(a1_2_0toa1_2_1_1));
+ ITEM_DIFF.put(NETHERRACK, andNewer(a1_2_0toa1_2_1_1));
+ ITEM_DIFF.put(COD, andNewer(a1_2_0toa1_2_1_1));
+ ITEM_DIFF.put(COOKED_COD, andNewer(a1_2_0toa1_2_1_1));
+ ITEM_DIFF.put(SOUL_SAND, andNewer(a1_2_0toa1_2_1_1));
+ ITEM_DIFF.put(CARVED_PUMPKIN, andNewer(a1_2_0toa1_2_1_1));
+ ITEM_DIFF.put(GLOWSTONE_DUST, andNewer(a1_2_0toa1_2_1_1));
+
+ ITEM_DIFF.put(FISHING_ROD, andNewer(a1_1_0toa1_1_2_1));
+ ITEM_DIFF.put(COMPASS, andNewer(a1_1_0toa1_1_2_1));
+
+ ITEM_DIFF.put(GRASS_BLOCK, andNewer(a1_0_15).add(single(c0_30cpe)));
+ ITEM_DIFF.put(BEDROCK, andNewer(a1_0_15).add(single(c0_30cpe)));
+ ITEM_DIFF.put(WATER_BUCKET, andNewer(a1_0_15).add(single(c0_30cpe)));
+ ITEM_DIFF.put(LAVA_BUCKET, andNewer(a1_0_15).add(single(c0_30cpe)));
+
+ ITEM_DIFF.put(WOODEN_AXE, andNewer(a1_0_15));
+ ITEM_DIFF.put(WOODEN_HOE, andNewer(a1_0_15));
+ ITEM_DIFF.put(WOODEN_PICKAXE, andNewer(a1_0_15));
+ ITEM_DIFF.put(WOODEN_SHOVEL, andNewer(a1_0_15));
+ ITEM_DIFF.put(WOODEN_SWORD, andNewer(a1_0_15));
+ ITEM_DIFF.put(STONE_AXE, andNewer(a1_0_15));
+ ITEM_DIFF.put(STONE_HOE, andNewer(a1_0_15));
+ ITEM_DIFF.put(STONE_PICKAXE, andNewer(a1_0_15));
+ ITEM_DIFF.put(STONE_SHOVEL, andNewer(a1_0_15));
+ ITEM_DIFF.put(STONE_SWORD, andNewer(a1_0_15));
+ ITEM_DIFF.put(IRON_AXE, andNewer(a1_0_15));
+ ITEM_DIFF.put(IRON_HOE, andNewer(a1_0_15));
+ ITEM_DIFF.put(IRON_PICKAXE, andNewer(a1_0_15));
+ ITEM_DIFF.put(IRON_SHOVEL, andNewer(a1_0_15));
+ ITEM_DIFF.put(IRON_SWORD, andNewer(a1_0_15));
+ ITEM_DIFF.put(GOLDEN_AXE, andNewer(a1_0_15));
+ ITEM_DIFF.put(GOLDEN_HOE, andNewer(a1_0_15));
+ ITEM_DIFF.put(GOLDEN_PICKAXE, andNewer(a1_0_15));
+ ITEM_DIFF.put(GOLDEN_SHOVEL, andNewer(a1_0_15));
+ ITEM_DIFF.put(GOLDEN_SWORD, andNewer(a1_0_15));
+ ITEM_DIFF.put(DIAMOND_AXE, andNewer(a1_0_15));
+ ITEM_DIFF.put(DIAMOND_HOE, andNewer(a1_0_15));
+ ITEM_DIFF.put(DIAMOND_PICKAXE, andNewer(a1_0_15));
+ ITEM_DIFF.put(DIAMOND_SHOVEL, andNewer(a1_0_15));
+ ITEM_DIFF.put(DIAMOND_SWORD, andNewer(a1_0_15));
+ ITEM_DIFF.put(LEATHER_HELMET, andNewer(a1_0_15));
+ ITEM_DIFF.put(LEATHER_CHESTPLATE, andNewer(a1_0_15));
+ ITEM_DIFF.put(LEATHER_LEGGINGS, andNewer(a1_0_15));
+ ITEM_DIFF.put(LEATHER_BOOTS, andNewer(a1_0_15));
+ ITEM_DIFF.put(CHAINMAIL_HELMET, andNewer(a1_0_15));
+ ITEM_DIFF.put(CHAINMAIL_CHESTPLATE, andNewer(a1_0_15));
+ ITEM_DIFF.put(CHAINMAIL_LEGGINGS, andNewer(a1_0_15));
+ ITEM_DIFF.put(CHAINMAIL_BOOTS, andNewer(a1_0_15));
+ ITEM_DIFF.put(IRON_HELMET, andNewer(a1_0_15));
+ ITEM_DIFF.put(IRON_CHESTPLATE, andNewer(a1_0_15));
+ ITEM_DIFF.put(IRON_LEGGINGS, andNewer(a1_0_15));
+ ITEM_DIFF.put(IRON_BOOTS, andNewer(a1_0_15));
+ ITEM_DIFF.put(GOLDEN_HELMET, andNewer(a1_0_15));
+ ITEM_DIFF.put(GOLDEN_CHESTPLATE, andNewer(a1_0_15));
+ ITEM_DIFF.put(GOLDEN_LEGGINGS, andNewer(a1_0_15));
+ ITEM_DIFF.put(GOLDEN_BOOTS, andNewer(a1_0_15));
+ ITEM_DIFF.put(DIAMOND_HELMET, andNewer(a1_0_15));
+ ITEM_DIFF.put(DIAMOND_CHESTPLATE, andNewer(a1_0_15));
+ ITEM_DIFF.put(DIAMOND_LEGGINGS, andNewer(a1_0_15));
+ ITEM_DIFF.put(DIAMOND_BOOTS, andNewer(a1_0_15));
+ ITEM_DIFF.put(BUCKET, andNewer(a1_0_15));
+ ITEM_DIFF.put(MILK_BUCKET, andNewer(a1_0_15));
+ ITEM_DIFF.put(FLINT_AND_STEEL, andNewer(a1_0_15));
+ ITEM_DIFF.put(SADDLE, andNewer(a1_0_15));
+ ITEM_DIFF.put(OAK_BOAT, andNewer(a1_0_15));
+ ITEM_DIFF.put(RAIL, andNewer(a1_0_15));
+ ITEM_DIFF.put(MINECART, andNewer(a1_0_15));
+ ITEM_DIFF.put(CHEST_MINECART, andNewer(a1_0_15));
+ ITEM_DIFF.put(FURNACE_MINECART, andNewer(a1_0_15));
+ ITEM_DIFF.put(SNOWBALL, andNewer(a1_0_15));
+ ITEM_DIFF.put(EGG, andNewer(a1_0_15));
+ ITEM_DIFF.put(BOW, andNewer(a1_0_15));
+ ITEM_DIFF.put(ARROW, andNewer(a1_0_15));
+ ITEM_DIFF.put(APPLE, andNewer(a1_0_15));
+ ITEM_DIFF.put(GOLDEN_APPLE, andNewer(a1_0_15));
+ ITEM_DIFF.put(PORKCHOP, andNewer(a1_0_15));
+ ITEM_DIFF.put(COOKED_PORKCHOP, andNewer(a1_0_15));
+ ITEM_DIFF.put(BREAD, andNewer(a1_0_15));
+ ITEM_DIFF.put(MUSHROOM_STEW, andNewer(a1_0_15));
+ ITEM_DIFF.put(COAL, andNewer(a1_0_15));
+ ITEM_DIFF.put(IRON_INGOT, andNewer(a1_0_15));
+ ITEM_DIFF.put(GOLD_INGOT, andNewer(a1_0_15));
+ ITEM_DIFF.put(DIAMOND, andNewer(a1_0_15));
+ ITEM_DIFF.put(STICK, andNewer(a1_0_15));
+ ITEM_DIFF.put(FLINT, andNewer(a1_0_15));
+ ITEM_DIFF.put(WHEAT, andNewer(a1_0_15));
+ ITEM_DIFF.put(STRING, andNewer(a1_0_15));
+ ITEM_DIFF.put(FEATHER, andNewer(a1_0_15));
+ ITEM_DIFF.put(LEATHER, andNewer(a1_0_15));
+ ITEM_DIFF.put(SLIME_BALL, andNewer(a1_0_15));
+ ITEM_DIFF.put(CLAY, andNewer(a1_0_15));
+ ITEM_DIFF.put(CLAY_BALL, andNewer(a1_0_15));
+ ITEM_DIFF.put(BOWL, andNewer(a1_0_15));
+ ITEM_DIFF.put(BRICK, andNewer(a1_0_15));
+ ITEM_DIFF.put(PAPER, andNewer(a1_0_15));
+ ITEM_DIFF.put(BOOK, andNewer(a1_0_15));
+ ITEM_DIFF.put(REDSTONE, andNewer(a1_0_15));
+ ITEM_DIFF.put(GUNPOWDER, andNewer(a1_0_15));
+ ITEM_DIFF.put(REDSTONE_TORCH, andNewer(a1_0_15));
+ ITEM_DIFF.put(LEVER, andNewer(a1_0_15));
+ ITEM_DIFF.put(STONE_BUTTON, andNewer(a1_0_15));
+ ITEM_DIFF.put(OAK_PRESSURE_PLATE, andNewer(a1_0_15));
+ ITEM_DIFF.put(STONE_PRESSURE_PLATE, andNewer(a1_0_15));
+ ITEM_DIFF.put(CHEST, andNewer(a1_0_15));
+ ITEM_DIFF.put(FURNACE, andNewer(a1_0_15));
+ ITEM_DIFF.put(REDSTONE_ORE, andNewer(a1_0_15));
+ ITEM_DIFF.put(JUKEBOX, andNewer(a1_0_15));
+ ITEM_DIFF.put(OAK_DOOR, andNewer(a1_0_15));
+ ITEM_DIFF.put(IRON_DOOR, andNewer(a1_0_15));
+ ITEM_DIFF.put(OAK_SIGN, andNewer(a1_0_15));
+ ITEM_DIFF.put(LADDER, andNewer(a1_0_15));
+ ITEM_DIFF.put(TORCH, andNewer(a1_0_15));
+ ITEM_DIFF.put(CRAFTING_TABLE, andNewer(a1_0_15));
+ ITEM_DIFF.put(CACTUS, andNewer(a1_0_15));
+ ITEM_DIFF.put(SUGAR_CANE, andNewer(a1_0_15));
+ ITEM_DIFF.put(WHEAT_SEEDS, andNewer(a1_0_15));
+ ITEM_DIFF.put(FARMLAND, andNewer(a1_0_15));
+ ITEM_DIFF.put(SNOW, andNewer(a1_0_15));
+ ITEM_DIFF.put(SNOW_BLOCK, andNewer(a1_0_15));
+ ITEM_DIFF.put(ICE, andNewer(a1_0_15));
+ ITEM_DIFF.put(DIAMOND_ORE, andNewer(a1_0_15));
+ ITEM_DIFF.put(DIAMOND_BLOCK, andNewer(a1_0_15));
+ ITEM_DIFF.put(OAK_FENCE, andNewer(a1_0_15));
+ ITEM_DIFF.put(OAK_STAIRS, andNewer(a1_0_15));
+ ITEM_DIFF.put(COBBLESTONE_STAIRS, andNewer(a1_0_15));
+
+ ITEM_DIFF.put(OBSIDIAN, andNewer(c0_30cpe));
+ ITEM_DIFF.put(TNT, andNewer(c0_30cpe));
+ ITEM_DIFF.put(BOOKSHELF, andNewer(c0_30cpe));
+ ITEM_DIFF.put(IRON_BLOCK, andNewer(c0_30cpe));
+ ITEM_DIFF.put(BRICKS, andNewer(c0_30cpe));
+ ITEM_DIFF.put(COAL_ORE, andNewer(c0_30cpe));
+ ITEM_DIFF.put(GOLD_ORE, andNewer(c0_30cpe));
+ ITEM_DIFF.put(IRON_ORE, andNewer(c0_30cpe));
+ ITEM_DIFF.put(MOSSY_COBBLESTONE, andNewer(c0_30cpe));
+ ITEM_DIFF.put(SMOOTH_STONE_SLAB, andNewer(c0_30cpe));
+
+ ITEM_DIFF.put(DANDELION, andNewer(c0_0_20ac0_27));
+ ITEM_DIFF.put(POPPY, andNewer(c0_0_20ac0_27));
+ ITEM_DIFF.put(BROWN_MUSHROOM, andNewer(c0_0_20ac0_27));
+ ITEM_DIFF.put(RED_MUSHROOM, andNewer(c0_0_20ac0_27));
+ ITEM_DIFF.put(GOLD_BLOCK, andNewer(c0_0_20ac0_27));
+ ITEM_DIFF.put(WHITE_WOOL, andNewer(c0_0_20ac0_27));
+
+ ITEM_DIFF.put(SPONGE, andNewer(c0_0_19a_06));
+ ITEM_DIFF.put(GLASS, andNewer(c0_0_19a_06));
+
+ ITEM_DIFF.put(STONE, andNewer(c0_0_15a_1));
+ ITEM_DIFF.put(DIRT, andNewer(c0_0_15a_1));
+ ITEM_DIFF.put(COBBLESTONE, andNewer(c0_0_15a_1));
+ ITEM_DIFF.put(OAK_PLANKS, andNewer(c0_0_15a_1));
+ ITEM_DIFF.put(OAK_SAPLING, andNewer(c0_0_15a_1));
+ ITEM_DIFF.put(OAK_LOG, andNewer(c0_0_15a_1));
+ ITEM_DIFF.put(OAK_LEAVES, andNewer(c0_0_15a_1));
+ ITEM_DIFF.put(SAND, andNewer(c0_0_15a_1));
+ ITEM_DIFF.put(GRAVEL, andNewer(c0_0_15a_1));
+
+ EXTENDED_CLASSIC_ITEMS.add(COBBLESTONE_SLAB);
+ EXTENDED_CLASSIC_ITEMS.add(DEAD_BUSH);
+ EXTENDED_CLASSIC_ITEMS.add(SANDSTONE);
+ EXTENDED_CLASSIC_ITEMS.add(SNOW);
+ EXTENDED_CLASSIC_ITEMS.add(TORCH);
+ EXTENDED_CLASSIC_ITEMS.add(BROWN_WOOL);
+ EXTENDED_CLASSIC_ITEMS.add(ICE);
+ EXTENDED_CLASSIC_ITEMS.add(CHISELED_QUARTZ_BLOCK);
+ EXTENDED_CLASSIC_ITEMS.add(NETHER_QUARTZ_ORE);
+ EXTENDED_CLASSIC_ITEMS.add(QUARTZ_PILLAR);
+ EXTENDED_CLASSIC_ITEMS.add(JUKEBOX);
+ EXTENDED_CLASSIC_ITEMS.add(STONE_BRICKS);
+
+ // https://minecraft.gamepedia.com/Java_Edition_version_history
+ }
+
+ public static boolean keepItem(final Item item) {
+ if (ProtocolHack.getTargetVersion().equals(c0_30cpe)) {
+ final ClientPlayNetworkHandler handler = MinecraftClient.getInstance().getNetworkHandler();
+ if (handler == null) return true;
+ final ExtensionProtocolMetadataStorage extensionProtocol = ((IClientConnection)handler.getConnection()).viaFabricPlus$getUserConnection().get(ExtensionProtocolMetadataStorage.class);
+ if (extensionProtocol == null) return false;
+ if (extensionProtocol.hasServerExtension(ClassicProtocolExtension.CUSTOM_BLOCKS, 1) && EXTENDED_CLASSIC_ITEMS.contains(item)) {
+ return true;
+ }
+ }
+
+ return !ITEM_DIFF.containsKey(item) || ITEM_DIFF.get(item).contains(ProtocolHack.getTargetVersion() /*ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(ITEM_DIFF.get(item)*/);
+ }
+
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/diff/RecipesPre1_12.java b/src/main/java/de/florianmichael/viafabricplus/fixes/diff/RecipesPre1_12.java
deleted file mode 100644
index 0e138598c..000000000
--- a/src/main/java/de/florianmichael/viafabricplus/fixes/diff/RecipesPre1_12.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
- * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
- * Copyright (C) 2023 RK_01/RaphiMC and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package de.florianmichael.viafabricplus.fixes.diff;
-
-import net.minecraft.block.ConcretePowderBlock;
-import net.minecraft.block.GlazedTerracottaBlock;
-import net.minecraft.block.ShulkerBoxBlock;
-import net.minecraft.client.MinecraftClient;
-import net.minecraft.inventory.RecipeInputInventory;
-import net.minecraft.item.BlockItem;
-import net.minecraft.item.Item;
-import net.minecraft.item.ItemStack;
-import net.minecraft.item.Items;
-import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
-import net.minecraft.recipe.*;
-import net.minecraft.screen.ScreenHandler;
-import net.raphimc.vialoader.util.VersionEnum;
-
-import java.util.List;
-
-/**
- * Handles all recipe related stuff for versions older than 1.12.
- */
-public class RecipesPre1_12 {
-
- /**
- * Removes recipes that are not supported in 1.11 and older versions.
- *
- * @param recipes List of recipes
- * @param version Version of the client
- */
- public static void editRecipes(final List> recipes, final VersionEnum version) {
- final var registryManager = MinecraftClient.getInstance().world.getRegistryManager();
-
- recipes.removeIf(recipe -> {
- if (recipe.getResult(registryManager).getItem() instanceof BlockItem block) {
- return block.getBlock() instanceof ConcretePowderBlock || block.getBlock() instanceof GlazedTerracottaBlock;
- }
- return false;
- });
-
- if (version.isOlderThanOrEqualTo(VersionEnum.r1_11)) {
- recipes.removeIf(recipe -> recipe.getResult(registryManager).getItem() == Items.IRON_NUGGET);
-
- if (version.isOlderThanOrEqualTo(VersionEnum.r1_10)) {
- recipes.removeIf(recipe -> {
- Item item = recipe.getResult(registryManager).getItem();
- if (item instanceof BlockItem blockItem) {
- return blockItem.getBlock() instanceof ShulkerBoxBlock;
- } else if (item == Items.OBSERVER || item == Items.IRON_NUGGET) {
- return true;
- } else if (item == Items.GOLD_NUGGET) {
- return recipe.getSerializer() == RecipeSerializer.SMELTING;
- } else {
- return false;
- }
- });
- }
-
- if (version.isOlderThanOrEqualTo(VersionEnum.r1_9_3tor1_9_4)) {
- recipes.removeIf(recipe -> recipe.getResult(registryManager).getItem() == Items.BONE_BLOCK);
- }
- }
- }
-
- /**
- * Sets the result slot of a crafting screen handler to the correct item stack. In MC <= 1.11.2 the result slot
- * is not updated when the input slots change, so we need to update it manually, Spigot and Paper re-syncs the slot,
- * so we don't notice this bug on servers that use Spigot or Paper
- *
- * @param syncId The sync id of the screen handler
- * @param screenHandler The screen handler
- * @param inventory The inventory of the screen handler
- */
- public static void setCraftingResultSlot(final int syncId, final ScreenHandler screenHandler, final RecipeInputInventory inventory) {
- final var network = MinecraftClient.getInstance().getNetworkHandler();
- if (network == null) return;
-
- final var world = MinecraftClient.getInstance().world;
-
- final var result = network.getRecipeManager().
- getFirstMatch(RecipeType.CRAFTING, inventory, world). // Get the first matching recipe
- map(recipe -> recipe.value().craft(inventory, world.getRegistryManager())). // Craft the recipe to get the result
- orElse(ItemStack.EMPTY); // If there is no recipe, set the result to air
-
- // Update the result slot
- network.onScreenHandlerSlotUpdate(new ScreenHandlerSlotUpdateS2CPacket(syncId, screenHandler.getRevision(), 0, result));
- }
-}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/diff/RenderableGlyphDiff.java b/src/main/java/de/florianmichael/viafabricplus/fixes/diff/RenderableGlyphDiff.java
new file mode 100644
index 000000000..f6cdd3e84
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/diff/RenderableGlyphDiff.java
@@ -0,0 +1,982 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.fixes.diff;
+
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
+import it.unimi.dsi.fastutil.ints.IntConsumer;
+import net.raphimc.vialoader.util.VersionEnum;
+
+import static java.util.stream.IntStream.rangeClosed;
+import static net.raphimc.vialoader.util.VersionEnum.*;
+
+public class RenderableGlyphDiff {
+
+ private static final Int2ObjectMap RENDERABLE_GLYPH_DIFF_LEGACY = new Int2ObjectOpenHashMap<>();
+ private static final Int2ObjectMap RENDERABLE_GLYPH_DIFF = new Int2ObjectOpenHashMap<>();
+
+ static {
+ rangeClosed(0, 887).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(890, 894).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(900, 906).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(908, c0_0_15a_1);
+ rangeClosed(910, 929).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(931, 1315).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(1329, 1366).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(1369, 1418).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(1423, c0_0_15a_1);
+ rangeClosed(1425, 1479).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(1488, 1514).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(1520, 1524).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(1536, 1539).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(1542, 1563).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(1566, 1567).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(1569, 1630).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(1632, 1805).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(1807, 1866).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(1869, 1969).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(1984, 2042).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2305, 2361).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2364, 2381).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2384, 2388).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2392, 2418).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2427, 2431).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2433, 2435).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2437, 2444).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2447, 2448).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2451, 2472).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2474, 2480).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(2482, c0_0_15a_1);
+ rangeClosed(2486, 2489).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2492, 2500).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2503, 2504).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2507, 2510).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(2519, c0_0_15a_1);
+ rangeClosed(2524, 2525).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2527, 2531).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2534, 2554).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2561, 2563).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2565, 2570).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2575, 2576).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2579, 2600).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2602, 2608).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2610, 2611).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2613, 2614).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2616, 2617).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(2620, c0_0_15a_1);
+ rangeClosed(2622, 2626).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2631, 2632).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2635, 2637).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(2641, c0_0_15a_1);
+ rangeClosed(2649, 2652).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(2654, c0_0_15a_1);
+ rangeClosed(2662, 2677).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2689, 2691).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2693, 2701).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2703, 2705).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2707, 2728).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2730, 2736).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2738, 2739).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2741, 2745).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2748, 2757).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2759, 2761).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2763, 2765).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(2768, c0_0_15a_1);
+ rangeClosed(2784, 2787).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2790, 2799).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(2801, c0_0_15a_1);
+ rangeClosed(2817, 2819).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2821, 2828).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2831, 2832).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2835, 2856).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2858, 2864).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2866, 2867).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2869, 2873).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2876, 2884).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2887, 2888).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2891, 2893).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2902, 2903).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2908, 2909).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2911, 2915).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2918, 2929).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2946, 2947).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2949, 2954).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2958, 2960).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2962, 2965).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2969, 2970).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(2972, c0_0_15a_1);
+ rangeClosed(2974, 2975).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2979, 2980).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2984, 2986).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(2990, 3001).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3006, 3010).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3014, 3016).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3018, 3021).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(3024, c0_0_15a_1);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(3031, c0_0_15a_1);
+ rangeClosed(3046, 3066).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3073, 3075).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3077, 3084).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3086, 3088).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3090, 3112).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3114, 3123).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3125, 3129).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3133, 3140).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3142, 3144).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3146, 3149).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3157, 3158).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3160, 3161).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3168, 3171).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3174, 3183).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3192, 3199).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3202, 3203).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3205, 3212).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3214, 3216).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3218, 3240).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3242, 3251).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3253, 3257).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3260, 3268).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3270, 3272).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3274, 3277).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3285, 3286).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(3294, c0_0_15a_1);
+ rangeClosed(3296, 3299).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3302, 3311).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3313, 3314).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3330, 3331).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3333, 3340).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3342, 3344).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3346, 3368).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3370, 3385).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3389, 3396).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3398, 3400).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3402, 3405).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(3415, c0_0_15a_1);
+ rangeClosed(3424, 3427).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3430, 3445).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3449, 3455).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3458, 3459).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3461, 3478).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3482, 3505).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3507, 3515).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(3517, c0_0_15a_1);
+ rangeClosed(3520, 3526).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(3530, c0_0_15a_1);
+ rangeClosed(3535, 3540).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(3542, c0_0_15a_1);
+ rangeClosed(3544, 3551).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3570, 3572).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3585, 3642).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3647, 3675).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3713, 3714).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(3716, c0_0_15a_1);
+ rangeClosed(3719, 3720).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(3722, c0_0_15a_1);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(3725, c0_0_15a_1);
+ rangeClosed(3732, 3735).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3737, 3743).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3745, 3747).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(3749, c0_0_15a_1);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(3751, c0_0_15a_1);
+ rangeClosed(3754, 3755).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3757, 3769).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3771, 3773).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3776, 3780).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(3782, c0_0_15a_1);
+ rangeClosed(3784, 3789).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3792, 3801).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3804, 3805).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3840, 3911).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3913, 3948).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3953, 3979).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3984, 3991).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(3993, 4028).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4030, 4044).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4046, 4052).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4096, 4249).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4254, 4293).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4304, 4348).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4352, 4441).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4447, 4514).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4520, 4601).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4608, 4680).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4682, 4685).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4688, 4694).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(4696, c0_0_15a_1);
+ rangeClosed(4698, 4701).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4704, 4744).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4746, 4749).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4752, 4784).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4786, 4789).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4792, 4798).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(4800, c0_0_15a_1);
+ rangeClosed(4802, 4805).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4808, 4822).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4824, 4880).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4882, 4885).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4888, 4954).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4959, 4988).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(4992, 5017).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(5024, 5108).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(5121, 5750).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(5760, 5788).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(5792, 5880).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(5888, 5900).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(5902, 5908).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(5920, 5942).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(5952, 5971).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(5984, 5996).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(5998, 6000).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6002, 6003).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6016, 6109).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6112, 6121).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6128, 6137).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6144, 6158).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6160, 6169).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6176, 6263).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6272, 6314).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6400, 6428).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6432, 6443).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6448, 6459).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(6464, c0_0_15a_1);
+ rangeClosed(6468, 6509).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6512, 6516).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6528, 6569).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6576, 6601).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6608, 6617).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6622, 6683).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6686, 6687).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6912, 6987).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(6992, 7036).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(7040, 7082).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(7086, 7097).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(7168, 7223).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(7227, 7241).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(7245, 7295).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(7424, 7654).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(7678, 7957).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(7960, 7965).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(7968, 8005).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8008, 8013).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8016, 8023).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(8025, c0_0_15a_1);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(8027, c0_0_15a_1);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(8029, c0_0_15a_1);
+ rangeClosed(8031, 8061).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8064, 8116).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8118, 8132).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8134, 8147).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8150, 8155).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8157, 8175).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8178, 8180).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8182, 8190).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8192, 8292).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8298, 8305).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8308, 8334).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8336, 8340).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8352, 8373).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(8381, c0_0_15a_1);
+ rangeClosed(8400, 8432).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8448, 8527).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8531, 8584).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(8592, 9143).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(9145, 9191).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(9193, 9194).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(9197, 9199).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(9204, 9213).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(9216, 9254).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(9280, 9290).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(9312, 9885).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(9888, 9916).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(9920, 9923).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(9935, c0_0_15a_1);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(9960, c0_0_15a_1);
+ rangeClosed(9985, 9988).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(9990, 9993).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(9996, 10023).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(10025, 10061).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(10063, 10066).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(10070, c0_0_15a_1);
+ rangeClosed(10072, 10078).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(10081, 10132).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(10136, 10159).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(10161, 10174).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(10176, 10186).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(10188, c0_0_15a_1);
+ rangeClosed(10192, 11084).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11088, 11092).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(11096, c0_0_15a_1);
+ rangeClosed(11264, 11310).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11312, 11358).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11360, 11375).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11377, 11389).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11392, 11498).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11513, 11557).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11568, 11621).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(11631, c0_0_15a_1);
+ rangeClosed(11648, 11670).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11680, 11686).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11688, 11694).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11696, 11702).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11704, 11710).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11712, 11718).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11720, 11726).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11728, 11734).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11736, 11742).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11744, 11824).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(11829, c0_0_15a_1);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(11832, c0_0_15a_1);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(11841, c0_0_15a_1);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(11851, c0_0_15a_1);
+ rangeClosed(11904, 11929).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(11931, 12019).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(12032, 12245).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(12272, 12283).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(12288, 12351).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(12353, 12438).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(12441, 12543).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(12549, 12589).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(12593, 12686).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(12688, 12727).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(12736, 12771).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(12784, 12830).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(12832, 12867).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(12880, 13054).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(13056, 19893).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(19904, 40899).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(40960, 42124).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(42128, 42182).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(42240, 42539).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(42560, 42591).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(42594, 42611).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(42620, 42647).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(42752, 42892).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(42928, c0_0_15a_1);
+ rangeClosed(43003, 43051).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(43072, 43127).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(43136, 43204).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(43214, 43225).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(43264, 43347).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(43359, c0_0_15a_1);
+ rangeClosed(43520, 43574).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(43584, 43597).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(43600, 43609).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(43612, 43615).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(44032, 55203).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(63744, 64045).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(64048, 64106).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(64112, 64217).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(64256, 64262).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(64275, 64279).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(64285, 64310).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(64312, 64316).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(64318, c0_0_15a_1);
+ rangeClosed(64320, 64321).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(64323, 64324).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(64326, 64433).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(64467, 64831).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(64848, 64911).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(64914, 64967).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(64976, 65021).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65024, 65049).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65056, 65062).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65072, 65106).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65108, 65126).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65128, 65131).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65136, 65140).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65142, 65276).forEach(putLegacy(c0_0_15a_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(65279, c0_0_15a_1);
+ rangeClosed(65281, 65470).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65474, 65479).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65482, 65487).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65490, 65495).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65498, 65500).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65504, 65510).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65512, 65518).forEach(putLegacy(c0_0_15a_1));
+ rangeClosed(65529, 65535).forEach(putLegacy(c0_0_15a_1));
+
+ rangeClosed(1316, 1327).forEach(putLegacy(r1_16));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(4295, r1_16);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(4301, r1_16);
+ rangeClosed(4349, 4351).forEach(putLegacy(r1_16));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(8382, r1_16);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(9924, r1_16);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(9928, r1_16);
+ rangeClosed(11390, 11391).forEach(putLegacy(r1_16));
+ rangeClosed(42900, 42901).forEach(putLegacy(r1_16));
+ rangeClosed(42920, 42921).forEach(putLegacy(r1_16));
+ rangeClosed(42927, 42927).forEach(putLegacy(r1_16));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(42948, r1_16);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(42950, r1_16);
+ rangeClosed(43856, 43857).forEach(putLegacy(r1_16));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(43875, r1_16);
+ rangeClosed(66352, 66378).forEach(putLegacy(r1_16));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(127754, r1_16);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(127783, r1_16);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(128293, r1_16);
+
+ rangeClosed(8528, 8530).forEach(putLegacy(r1_16_2));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(8585, r1_16_2);
+ rangeClosed(11242, 11243).forEach(putLegacy(r1_16_2));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(127907, r1_16_2);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(127993, r1_16_2);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(128305, r1_16_2);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(128481, r1_16_2);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(128737, r1_16_2);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(129514, r1_16_2);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(129683, r1_16_2);
+
+ rangeClosed(8374, 8380).forEach(putLegacy(r1_17_1));
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(8383, r1_17_1);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(9203, r1_17_1);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(127830, r1_17_1);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(128276, r1_17_1);
+ RENDERABLE_GLYPH_DIFF_LEGACY.put(129699, r1_17_1);
+
+ // 1.20 switch to using Unihex as a main font
+
+ rangeClosed(0, 2559).forEach(put(r1_20tor1_20_1));
+ rangeClosed(2561, 55295).forEach(put(r1_20tor1_20_1));
+ rangeClosed(61425, 61426).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(61429, r1_20tor1_20_1);
+ rangeClosed(63744, 65533).forEach(put(r1_20tor1_20_1));
+ rangeClosed(65536, 72543).forEach(put(r1_20tor1_20_1));
+ rangeClosed(72704, 73727).forEach(put(r1_20tor1_20_1));
+ rangeClosed(74650, 74751).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(74863, r1_20tor1_20_1);
+ rangeClosed(74869, 74879).forEach(put(r1_20tor1_20_1));
+ rangeClosed(75076, 77823).forEach(put(r1_20tor1_20_1));
+ rangeClosed(78895, 82943).forEach(put(r1_20tor1_20_1));
+ rangeClosed(83527, 92159).forEach(put(r1_20tor1_20_1));
+ rangeClosed(92729, 94207).forEach(put(r1_20tor1_20_1));
+ rangeClosed(100344, 100351).forEach(put(r1_20tor1_20_1));
+ rangeClosed(101120, 101631).forEach(put(r1_20tor1_20_1));
+ rangeClosed(101641, 128124).forEach(put(r1_20tor1_20_1));
+ rangeClosed(128126, 131069).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(131083, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(131207, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(131209, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(131234, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(131236, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(131276, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(131428, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(131490, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(131603, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(131883, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(131953, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(131969, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(132089, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(132170, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(132361, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(132566, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(132648, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(132726, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(132943, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(133127, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(133178, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(133305, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(133500, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(133533, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(133843, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(133917, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(134047, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(134352, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(134469, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(134625, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(134756, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(134765, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(134805, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(135007, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(135359, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(135681, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(135741, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(135765, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(135796, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(135803, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(135895, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(135908, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(135933, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(135963, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(135990, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(136004, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(136090, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(136132, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(136211, r1_20tor1_20_1);
+ rangeClosed(136301, 136302).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(136663, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(136775, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(136884, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(136966, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(137026, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(137405, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(137667, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(138326, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(138541, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(138565, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(138594, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(138616, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(138642, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(138652, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(138657, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(138679, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(138720, r1_20tor1_20_1);
+ rangeClosed(138803, 138804).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(139038, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(139126, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(139258, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(139643, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(139800, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(140062, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(140205, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(141043, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(141403, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(141483, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(141711, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(142008, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(142150, r1_20tor1_20_1);
+ rangeClosed(142159, 142160).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(142246, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(142365, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(142372, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(142817, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(143798, r1_20tor1_20_1);
+ rangeClosed(143811, 143812).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(143861, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(144242, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(144336, r1_20tor1_20_1);
+ rangeClosed(144338, 144339).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(144341, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(144346, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(144351, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(144356, r1_20tor1_20_1);
+ rangeClosed(144458, 144459).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(144465, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(144485, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(144612, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(144730, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(144788, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(144836, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(144843, r1_20tor1_20_1);
+ rangeClosed(144952, 144954).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(144967, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(145164, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(145180, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(145215, r1_20tor1_20_1);
+ rangeClosed(145251, 145252).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(145383, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(145407, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(145444, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(145469, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(146072, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(146559, r1_20tor1_20_1);
+ rangeClosed(146583, 146584).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(146686, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(146688, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(146702, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(146752, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(146899, r1_20tor1_20_1);
+ rangeClosed(146937, 146938).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(146979, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(147326, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(147606, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(147715, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(147910, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(147966, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(147982, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(148412, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(149033, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(149157, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(149489, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(149654, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(149737, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(149979, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(150017, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(150093, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(150141, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(150217, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(150358, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(150383, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(150550, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(150804, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(151054, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(151095, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(151146, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(151179, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(151626, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(151637, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(151842, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(151977, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(152013, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(152037, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(152094, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(152140, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(152622, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(152718, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(152793, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(152846, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(152882, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(152930, r1_20tor1_20_1);
+ rangeClosed(152999, 153000).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(153457, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(153513, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(153524, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(154052, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(154068, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(154327, r1_20tor1_20_1);
+ rangeClosed(154339, 154340).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(154353, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(154546, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(154699, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(154724, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155041, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155182, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155209, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155222, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155234, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155237, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155330, r1_20tor1_20_1);
+ rangeClosed(155351, 155352).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(155368, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155427, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155484, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155604, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155616, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155643, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155660, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155671, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155744, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(155885, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(156193, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(156272, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(156294, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(156492, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(156674, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(156813, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(157302, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(157310, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(157360, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(157469, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(157564, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(157917, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(157930, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(158033, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(158063, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(158173, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(158238, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(158296, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(158348, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(158391, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(158463, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(158556, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(158753, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(158761, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(158835, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(158941, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(159296, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(159333, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(159636, r1_20tor1_20_1);
+ rangeClosed(159734, 159736).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(159988, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(160013, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(160057, r1_20tor1_20_1);
+ rangeClosed(160730, 160731).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(160766, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(160784, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(160841, r1_20tor1_20_1);
+ rangeClosed(161300, 161301).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(161329, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(161412, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(161427, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(161550, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(161571, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(161618, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(161970, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(162181, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(162436, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(162739, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(162750, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(162759, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(163000, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(163232, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(163344, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(163503, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(163767, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(163833, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(163978, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(164027, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(164471, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(164482, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(164595, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(164813, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(164872, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(164876, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(164949, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(165227, r1_20tor1_20_1);
+ rangeClosed(165320, 165321).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(165496, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(165525, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(165591, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(165626, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(165856, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166214, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166217, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166251, r1_20tor1_20_1);
+ rangeClosed(166279, 166280).forEach(put(r1_20tor1_20_1));
+ rangeClosed(166330, 166331).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(166336, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166415, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166430, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166441, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166467, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166513, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166553, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166605, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166621, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166628, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166726, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166729, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166734, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166849, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166895, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166983, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166991, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166993, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(166996, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(167184, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(167281, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(167419, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(167439, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(167455, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(167478, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(167561, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(167577, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(167659, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(167730, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(167928, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(168608, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(168625, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(169104, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(169423, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(169599, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(169712, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(169753, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(169808, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(170000, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(170182, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(170610, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(171477, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(171483, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(171541, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(171581, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(171593, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(171658, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(171716, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(171739, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(171753, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(171902, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(171907, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(171916, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(171982, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(172058, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(172079, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(172162, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(172281, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(172432, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(172940, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(173111, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(173553, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(173570, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(173594, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(173746, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(174045, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(174141, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(174331, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(174359, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(174640, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(174646, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(174680, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(176034, r1_20tor1_20_1);
+ rangeClosed(176423, 176424).forEach(put(r1_20tor1_20_1));
+ rangeClosed(176439, 176440).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(176621, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(176896, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(176995, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177007, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177010, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177021, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177156, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177168, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177171, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177249, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177383, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177391, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177398, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177401, r1_20tor1_20_1);
+ rangeClosed(177421, 177422).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(177462, r1_20tor1_20_1);
+ rangeClosed(177582, 177583).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(177587, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177639, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177652, r1_20tor1_20_1);
+ rangeClosed(177692, 177693).forEach(put(r1_20tor1_20_1));
+ rangeClosed(177702, 177704).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(177706, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177708, r1_20tor1_20_1);
+ rangeClosed(177813, 177814).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(177837, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(177901, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(178089, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(178117, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(178150, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(178167, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(178169, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(178172, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(178182, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(178186, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(178204, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(178360, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(178840, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(178887, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(179039, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(179042, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(179068, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(179075, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(179227, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(179575, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(179591, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(179703, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(179753, r1_20tor1_20_1);
+ rangeClosed(180265, 180266).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(180393, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(180426, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(180693, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(180697, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(180729, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(180860, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(180872, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(180900, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181015, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181083, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181089, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181092, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181384, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181396, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181399, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181570, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181643, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181779, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181784, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181793, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181801, r1_20tor1_20_1);
+ rangeClosed(181803, 181805).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(181807, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(181826, r1_20tor1_20_1);
+ rangeClosed(181834, 181835).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(182060, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182063, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182175, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182209, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182252, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182269, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182489, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182494, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182497, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182515, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182535, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182538, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182557, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182786, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182798, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182909, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182953, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(182994, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183081, r1_20tor1_20_1);
+ rangeClosed(183085, 183086).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(183089, r1_20tor1_20_1);
+ rangeClosed(183096, 183097).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(183099, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183103, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183105, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183114, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183118, r1_20tor1_20_1);
+ rangeClosed(183130, 183131).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(183140, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183145, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183148, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183151, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183155, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183158, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183160, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183164, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183217, r1_20tor1_20_1);
+ rangeClosed(183231, 183232).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(183246, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183382, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183391, r1_20tor1_20_1);
+ rangeClosed(183541, 183542).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(183549, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183551, r1_20tor1_20_1);
+ rangeClosed(183554, 183555).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(183562, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183688, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183691, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183693, r1_20tor1_20_1);
+ rangeClosed(183695, 183696).forEach(put(r1_20tor1_20_1));
+ rangeClosed(183711, 183712).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(183720, r1_20tor1_20_1);
+ rangeClosed(183725, 183726).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(183765, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183832, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183834, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183843, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183846, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183850, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183932, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183944, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(183955, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(185218, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(185668, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(194692, r1_20tor1_20_1);
+ RENDERABLE_GLYPH_DIFF.put(194742, r1_20tor1_20_1);
+ rangeClosed(200413, 200414).forEach(put(r1_20tor1_20_1));
+ RENDERABLE_GLYPH_DIFF.put(200812, r1_20tor1_20_1);
+ rangeClosed(917504, 917631).forEach(put(r1_20tor1_20_1));
+ rangeClosed(917760, 917999).forEach(put(r1_20tor1_20_1));
+ rangeClosed(1048574, 1048575).forEach(put(r1_20tor1_20_1));
+ }
+
+ public static boolean isGlyphRenderable(final int codePoint) {
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(r1_20tor1_20_1)) {
+ return RENDERABLE_GLYPH_DIFF.containsKey(codePoint) && ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(RENDERABLE_GLYPH_DIFF.get(codePoint));
+ }
+
+ return RENDERABLE_GLYPH_DIFF_LEGACY.containsKey(codePoint) && ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(RENDERABLE_GLYPH_DIFF_LEGACY.get(codePoint));
+ }
+
+ private static IntConsumer putLegacy(final VersionEnum version) {
+ return i -> RENDERABLE_GLYPH_DIFF_LEGACY.put(i, version);
+ }
+
+ private static IntConsumer put(final VersionEnum version) {
+ return i -> RENDERABLE_GLYPH_DIFF.put(i, version);
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/recipe/AddBannerPatternRecipe.java b/src/main/java/de/florianmichael/viafabricplus/fixes/recipe/AddBannerPatternRecipe.java
new file mode 100644
index 000000000..af592b52a
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/recipe/AddBannerPatternRecipe.java
@@ -0,0 +1,183 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.fixes.recipe;
+
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import net.minecraft.block.entity.BannerBlockEntity;
+import net.minecraft.inventory.RecipeInputInventory;
+import net.minecraft.item.BannerItem;
+import net.minecraft.item.DyeItem;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NbtCompound;
+import net.minecraft.nbt.NbtList;
+import net.minecraft.recipe.RecipeSerializer;
+import net.minecraft.recipe.SpecialCraftingRecipe;
+import net.minecraft.recipe.SpecialRecipeSerializer;
+import net.minecraft.recipe.book.CraftingRecipeCategory;
+import net.minecraft.registry.DynamicRegistryManager;
+import net.minecraft.util.DyeColor;
+import net.minecraft.world.World;
+import net.raphimc.vialoader.util.VersionEnum;
+
+public class AddBannerPatternRecipe extends SpecialCraftingRecipe {
+
+ public static final RecipeSerializer SERIALIZER = new SpecialRecipeSerializer<>(AddBannerPatternRecipe::new);
+
+ public AddBannerPatternRecipe(CraftingRecipeCategory craftingRecipeCategory) {
+ super(craftingRecipeCategory);
+ }
+
+ @Override
+ public boolean matches(RecipeInputInventory inv, World world) {
+ boolean foundBanner = false;
+ for (int i = 0; i < inv.size(); i++) {
+ ItemStack stack = inv.getStack(i);
+ if (stack.getItem() instanceof BannerItem) {
+ if (foundBanner)
+ return false;
+ if (BannerBlockEntity.getPatternCount(stack) >= 6)
+ return false;
+ foundBanner = true;
+ }
+ }
+ return foundBanner && getBannerPattern(inv) != null;
+ }
+
+ @Override
+ public ItemStack craft(RecipeInputInventory inv, DynamicRegistryManager registryManager) {
+ ItemStack result = ItemStack.EMPTY;
+
+ for (int i = 0; i < inv.size(); i++) {
+ ItemStack stack = inv.getStack(i);
+ if (!stack.isEmpty() && stack.getItem() instanceof BannerItem) {
+ result = stack.copy();
+ result.setCount(1);
+ break;
+ }
+ }
+
+ BannerPattern_1_13_2 pattern = getBannerPattern(inv);
+ if (pattern != null) {
+ DyeColor color = ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2) ? DyeColor.BLACK : DyeColor.WHITE;
+ for (int i = 0; i < inv.size(); i++) {
+ Item item = inv.getStack(i).getItem();
+ if (item instanceof DyeItem dyeItem) {
+ color = dyeItem.getColor();
+ }
+ }
+
+ NbtCompound tileEntityNbt = result.getOrCreateSubNbt("BlockEntityTag");
+ NbtList patterns;
+ if (tileEntityNbt.contains("Patterns", 9)) {
+ patterns = tileEntityNbt.getList("Patterns", 10);
+ } else {
+ patterns = new NbtList();
+ tileEntityNbt.put("Patterns", patterns);
+ }
+ NbtCompound patternNbt = new NbtCompound();
+ patternNbt.putString("Pattern", pattern.getId());
+ patternNbt.putInt("Color", color.getId());
+ patterns.add(patternNbt);
+ }
+
+ return result;
+ }
+
+ @Override
+ public boolean fits(int width, int height) {
+ return width >= 3 && height >= 3;
+ }
+
+ @Override
+ public RecipeSerializer getSerializer() {
+ return SERIALIZER;
+ }
+
+ private static BannerPattern_1_13_2 getBannerPattern(RecipeInputInventory inv) {
+ for (BannerPattern_1_13_2 pattern : BannerPattern_1_13_2.values()) {
+ if (!pattern.isCraftable())
+ continue;
+
+ boolean matches = true;
+ if (pattern.hasBaseStack()) {
+ boolean foundBaseItem = false;
+ boolean foundDye = false;
+ for (int i = 0; i < inv.size(); i++) {
+ ItemStack stack = inv.getStack(i);
+ if (!stack.isEmpty() && !(stack.getItem() instanceof BannerItem)) {
+ if (stack.getItem() instanceof DyeItem) {
+ if (foundDye) {
+ matches = false;
+ break;
+ }
+ foundDye = true;
+ } else {
+ if (foundBaseItem || !(!stack.isEmpty() && ItemStack.areItemsEqual(stack, pattern.getBaseStack()))) {
+ matches = false;
+ break;
+ }
+ foundBaseItem = true;
+ }
+ }
+ }
+ if (!foundBaseItem || (!foundDye && ProtocolHack.getTargetVersion().isNewerThan(VersionEnum.r1_10))) matches = false;
+ } else if (inv.size() == pattern.getRecipePattern().length * pattern.getRecipePattern()[0].length()) {
+ DyeColor patternColor = null;
+ for (int i = 0; i < inv.size(); i++) {
+ int row = i / 3;
+ int col = i % 3;
+ ItemStack stack = inv.getStack(i);
+ Item item = stack.getItem();
+ if (!stack.isEmpty() && !(item instanceof BannerItem)) {
+ if (!(item instanceof DyeItem)) {
+ matches = false;
+ break;
+ }
+
+ DyeColor color = ((DyeItem) item).getColor();
+ if (patternColor != null && color != patternColor) {
+ matches = false;
+ break;
+ }
+
+ if (pattern.getRecipePattern()[row].charAt(col) == ' ') {
+ matches = false;
+ break;
+ }
+
+ patternColor = color;
+ } else if (pattern.getRecipePattern()[row].charAt(col) != ' ') {
+ matches = false;
+ break;
+ }
+ }
+ } else {
+ matches = false;
+ }
+
+ if (matches)
+ return pattern;
+ }
+
+ return null;
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/recipe/BannerPattern_1_13_2.java b/src/main/java/de/florianmichael/viafabricplus/fixes/recipe/BannerPattern_1_13_2.java
new file mode 100644
index 000000000..4c50734b8
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/recipe/BannerPattern_1_13_2.java
@@ -0,0 +1,112 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.fixes.recipe;
+
+import net.minecraft.block.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+
+// safe from vanilla modification + removal of recipes
+public enum BannerPattern_1_13_2 {
+
+ BASE("b"),
+ SQUARE_BOTTOM_LEFT("bl", " ", " ", "# "),
+ SQUARE_BOTTOM_RIGHT("br", " ", " ", " #"),
+ SQUARE_TOP_LEFT("tl", "# ", " ", " "),
+ SQUARE_TOP_RIGHT("tr", " #", " ", " "),
+ STRIPE_BOTTOM("bs", " ", " ", "###"),
+ STRIPE_TOP("ts", "###", " ", " "),
+ STRIPE_LEFT("ls", "# ", "# ", "# "),
+ STRIPE_RIGHT("rs", " #", " #", " #"),
+ STRIPE_CENTER("cs", " # ", " # ", " # "),
+ STRIPE_MIDDLE("ms", " ", "###", " "),
+ STRIPE_DOWNRIGHT("drs", "# ", " # ", " #"),
+ STRIPE_DOWNLEFT("dls", " #", " # ", "# "),
+ STRIPE_SMALL("ss", "# #", "# #", " "),
+ CROSS("cr", "# #", " # ", "# #"),
+ STRAIGHT_CROSS("sc", " # ", "###", " # "),
+ TRIANGLE_BOTTOM("bt", " ", " # ", "# #"),
+ TRIANGLE_TOP("tt", "# #", " # ", " "),
+ TRIANGLES_BOTTOM("bts", " ", "# #", " # "),
+ TRIANGLES_TOP("tts", " # ", "# #", " "),
+ DIAGONAL_LEFT("ld", "## ", "# ", " "),
+ DIAGONAL_RIGHT("rd", " ", " #", " ##"),
+ DIAGONAL_LEFT_MIRROR("lud", " ", "# ", "## "),
+ DIAGONAL_RIGHT_MIRROR("rud", " ##", " #", " "),
+ CIRCLE_MIDDLE("mc", " ", " # ", " "),
+ RHOMBUS_MIDDLE("mr", " # ", "# #", " # "),
+ HALF_VERTICAL("vh", "## ", "## ", "## "),
+ HALF_HORIZONTAL("hh", "###", "###", " "),
+ HALF_VERTICAL_MIRROR("vhr", " ##", " ##", " ##"),
+ HALF_HORIZONTAL_MIRROR("hhb", " ", "###", "###"),
+ BORDER("bo", "###", "# #", "###"),
+ CURLY_BORDER("cbo", new ItemStack(Blocks.VINE)),
+ GRADIENT("gra", "# #", " # ", " # "),
+ GRADIENT_UP("gru", " # ", " # ", "# #"),
+ BRICKS("bri", new ItemStack(Blocks.BRICKS)),
+ GLOBE("glb"),
+ CREEPER("cre", new ItemStack(Items.CREEPER_HEAD)),
+ SKULL("sku", new ItemStack(Items.WITHER_SKELETON_SKULL)),
+ FLOWER("flo", new ItemStack(Blocks.OXEYE_DAISY)),
+ MOJANG("moj", new ItemStack(Items.ENCHANTED_GOLDEN_APPLE));
+
+ private final String id;
+ private final String[] recipePattern;
+ private ItemStack baseStack;
+
+ BannerPattern_1_13_2(String id) {
+ this.recipePattern = new String[3];
+ this.baseStack = ItemStack.EMPTY;
+ this.id = id;
+ }
+
+ BannerPattern_1_13_2(String id, ItemStack baseStack) {
+ this(id);
+ this.baseStack = baseStack;
+ }
+
+ BannerPattern_1_13_2(String id, String recipe1, String recipe2, String recipe3) {
+ this(id);
+ this.recipePattern[0] = recipe1;
+ this.recipePattern[1] = recipe2;
+ this.recipePattern[2] = recipe3;
+ }
+
+ public String getId() {
+ return this.id;
+ }
+
+ public boolean isCraftable() {
+ return !this.baseStack.isEmpty() || this.recipePattern[0] != null;
+ }
+
+ public boolean hasBaseStack() {
+ return !this.baseStack.isEmpty();
+ }
+
+ public ItemStack getBaseStack() {
+ return this.baseStack;
+ }
+
+ public String[] getRecipePattern() {
+ return this.recipePattern;
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/recipe/RecipeInfo.java b/src/main/java/de/florianmichael/viafabricplus/fixes/recipe/RecipeInfo.java
new file mode 100644
index 000000000..7b868e6ec
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/recipe/RecipeInfo.java
@@ -0,0 +1,217 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.fixes.recipe;
+
+import net.minecraft.item.ItemConvertible;
+import net.minecraft.item.ItemStack;
+import net.minecraft.recipe.*;
+import net.minecraft.recipe.book.CookingRecipeCategory;
+import net.minecraft.recipe.book.CraftingRecipeCategory;
+import net.minecraft.util.Identifier;
+import net.minecraft.util.collection.DefaultedList;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.function.Supplier;
+
+public final class RecipeInfo> {
+
+ private final Supplier> creator;
+ private final RecipeSerializer recipeType;
+ private final ItemStack output;
+ private String distinguisher = "";
+
+ private RecipeInfo(Supplier> creator, RecipeSerializer recipeType, ItemStack output) {
+ this.creator = creator;
+ this.recipeType = recipeType;
+ this.output = output;
+ }
+
+ public static > RecipeInfo of(Supplier> creator, RecipeSerializer recipeType, ItemStack output) {
+ return new RecipeInfo<>(creator, recipeType, output);
+ }
+
+ public static > RecipeInfo of(Supplier> creator, RecipeSerializer recipeType, ItemConvertible output) {
+ return of(creator, recipeType, new ItemStack(output));
+ }
+
+ public static > RecipeInfo of(Supplier> creator, RecipeSerializer recipeType, ItemConvertible output, int count) {
+ return of(creator, recipeType, new ItemStack(output, count));
+ }
+
+ public static RecipeInfo shaped(ItemStack output, Object... args) {
+ return shaped("", output, args);
+ }
+
+ public static RecipeInfo shaped(ItemConvertible output, Object... args) {
+ return shaped("", output, args);
+ }
+
+ public static RecipeInfo shaped(int count, ItemConvertible output, Object... args) {
+ return shaped("", count, output, args);
+ }
+
+ public static RecipeInfo shaped(String group, ItemStack output, Object... args) {
+ int i;
+ int width = 0;
+ List shape = new ArrayList<>();
+ for (i = 0; i < args.length && args[i] instanceof String str; i++) {
+ if (i == 0)
+ width = str.length();
+ else if (str.length() != width)
+ throw new IllegalArgumentException("Rows do not have consistent width");
+ shape.add(str);
+ }
+ var legend = new HashMap();
+ while (i < args.length && args[i] instanceof Character key) {
+ i++;
+ List items = new ArrayList<>();
+ for (; i < args.length && args[i] instanceof ItemConvertible; i++) {
+ items.add((ItemConvertible) args[i]);
+ }
+ legend.put(key, Ingredient.ofItems(items.toArray(new ItemConvertible[0])));
+ }
+ if (i != args.length)
+ throw new IllegalArgumentException("Unexpected argument at index " + i + ": " + args[i]);
+
+ int height = shape.size();
+ DefaultedList ingredients = DefaultedList.of();
+ for (String row : shape) {
+ for (int x = 0; x < width; x++) {
+ char key = row.charAt(x);
+ Ingredient ingredient = legend.get(key);
+ if (ingredient == null) {
+ if (key == ' ')
+ ingredient = Ingredient.EMPTY;
+ else
+ throw new IllegalArgumentException("Unknown character in shape: " + key);
+ }
+ ingredients.add(ingredient);
+ }
+ }
+
+ final int width_f = width;
+ return new RecipeInfo<>(() -> new ShapedRecipe(group, CraftingRecipeCategory.MISC, width_f, height, ingredients, output), RecipeSerializer.SHAPED, output);
+ }
+
+ public static RecipeInfo shaped(String group, ItemConvertible output, Object... args) {
+ return shaped(group, new ItemStack(output), args);
+ }
+
+ public static RecipeInfo shaped(String group, int count, ItemConvertible output, Object... args) {
+ return shaped(group, new ItemStack(output, count), args);
+ }
+
+ public static RecipeInfo shapeless(String group, ItemStack output, ItemConvertible... inputs) {
+ ItemConvertible[][] newInputs = new ItemConvertible[inputs.length][1];
+ for (int i = 0; i < inputs.length; i++)
+ newInputs[i] = new ItemConvertible[]{inputs[i]};
+ return shapeless(group, output, newInputs);
+ }
+
+ public static RecipeInfo shapeless(String group, ItemConvertible output, ItemConvertible... inputs) {
+ return shapeless(group, new ItemStack(output), inputs);
+ }
+
+ public static RecipeInfo shapeless(String group, int count, ItemConvertible output, ItemConvertible... inputs) {
+ return shapeless(group, new ItemStack(output, count), inputs);
+ }
+
+ public static RecipeInfo shapeless(String group, ItemStack output, ItemConvertible[]... inputs) {
+ DefaultedList ingredients = DefaultedList.of();
+ for (ItemConvertible[] input : inputs) {
+ ingredients.add(Ingredient.ofItems(input));
+ }
+ return new RecipeInfo<>(() -> new ShapelessRecipe(group, CraftingRecipeCategory.MISC, output, ingredients), RecipeSerializer.SHAPELESS, output);
+ }
+
+ public static RecipeInfo shapeless(String group, ItemConvertible output, ItemConvertible[]... inputs) {
+ return shapeless(group, new ItemStack(output), inputs);
+ }
+
+ public static RecipeInfo shapeless(String group, int count, ItemConvertible output, ItemConvertible[]... inputs) {
+ return shapeless(group, new ItemStack(output, count), inputs);
+ }
+
+ public static RecipeInfo shapeless(ItemStack output, ItemConvertible... inputs) {
+ return shapeless("", output, inputs);
+ }
+
+ public static RecipeInfo shapeless(ItemConvertible output, ItemConvertible... inputs) {
+ return shapeless("", output, inputs);
+ }
+
+ public static RecipeInfo shapeless(int count, ItemConvertible output, ItemConvertible... inputs) {
+ return shapeless("", count, output, inputs);
+ }
+
+ public static RecipeInfo shapeless(ItemStack output, ItemConvertible[]... inputs) {
+ return shapeless("", output, inputs);
+ }
+
+ public static RecipeInfo shapeless(ItemConvertible output, ItemConvertible[]... inputs) {
+ return shapeless("", output, inputs);
+ }
+
+ public static RecipeInfo shapeless(int count, ItemConvertible output, ItemConvertible[]... inputs) {
+ return shapeless("", count, output, inputs);
+ }
+
+ public static RecipeInfo smelting(ItemConvertible output, ItemConvertible input, float experience) {
+ return smelting(output, input, experience, 200);
+ }
+
+ public static RecipeInfo smelting(ItemConvertible output, Ingredient input, float experience) {
+ return smelting(output, input, experience, 200);
+ }
+
+ public static RecipeInfo smelting(ItemConvertible output, ItemConvertible input, float experience, int cookTime) {
+ return smelting(output, Ingredient.ofItems(input), experience, cookTime);
+ }
+
+ public static RecipeInfo smelting(ItemConvertible output, Ingredient input, float experience, int cookTime) {
+ ItemStack outputStack = new ItemStack(output);
+ return new RecipeInfo<>(() -> new SmeltingRecipe("", CookingRecipeCategory.MISC, input, outputStack, experience, cookTime), RecipeSerializer.SMELTING, outputStack);
+ }
+
+ public RecipeInfo distinguisher(String distinguisher) {
+ this.distinguisher = distinguisher;
+ return this;
+ }
+
+
+ public RecipeEntry> create(Identifier id) {
+ return new RecipeEntry>(id, this.creator.get());
+ }
+
+ public RecipeSerializer getRecipeType() {
+ return this.recipeType;
+ }
+
+ public ItemStack getOutput() {
+ return this.output;
+ }
+
+ public String getDistinguisher() {
+ return this.distinguisher;
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/fixes/recipe/Recipes1_11_2.java b/src/main/java/de/florianmichael/viafabricplus/fixes/recipe/Recipes1_11_2.java
new file mode 100644
index 000000000..5740ec295
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/fixes/recipe/Recipes1_11_2.java
@@ -0,0 +1,713 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.fixes.recipe;
+
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import net.minecraft.block.Blocks;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.inventory.RecipeInputInventory;
+import net.minecraft.item.ItemConvertible;
+import net.minecraft.item.ItemStack;
+import net.minecraft.item.Items;
+import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
+import net.minecraft.recipe.*;
+import net.minecraft.recipe.book.CraftingRecipeCategory;
+import net.minecraft.registry.tag.ItemTags;
+import net.minecraft.screen.ScreenHandler;
+import net.raphimc.vialoader.util.VersionEnum;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Recipes1_11_2 {
+
+ public static List> getRecipes() {
+ final List> recipes = new ArrayList<>();
+
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_4_2)) {
+ recipes.add(RecipeInfo.of(() -> new ArmorDyeRecipe(CraftingRecipeCategory.MISC), RecipeSerializer.ARMOR_DYE, Items.LEATHER_HELMET));
+ recipes.add(RecipeInfo.of(() -> new MapCloningRecipe(CraftingRecipeCategory.MISC), RecipeSerializer.MAP_CLONING, Items.FILLED_MAP, 2));
+ recipes.add(RecipeInfo.of(() -> new MapExtendingRecipe(CraftingRecipeCategory.MISC), RecipeSerializer.MAP_EXTENDING, Items.FILLED_MAP));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_4_6tor1_4_7)) {
+ recipes.add(RecipeInfo.of(() -> new FireworkRocketRecipe(CraftingRecipeCategory.MISC), RecipeSerializer.FIREWORK_ROCKET, Items.FIREWORK_ROCKET));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_11)) {
+ recipes.add(RecipeInfo.of(() -> new ShulkerBoxColoringRecipe(CraftingRecipeCategory.MISC), RecipeSerializer.SHULKER_BOX, Items.WHITE_SHULKER_BOX));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_9)) {
+ recipes.add(RecipeInfo.of(() -> new TippedArrowRecipe(CraftingRecipeCategory.MISC), RecipeSerializer.TIPPED_ARROW, Items.TIPPED_ARROW));
+ recipes.add(RecipeInfo.of(() -> new ShieldDecorationRecipe(CraftingRecipeCategory.MISC), RecipeSerializer.SHIELD_DECORATION, Items.SHIELD));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_8)) {
+ recipes.add(RecipeInfo.of(() -> new RepairItemRecipe(CraftingRecipeCategory.MISC), RecipeSerializer.REPAIR_ITEM, Items.WOODEN_SWORD));
+ recipes.add(RecipeInfo.of(() -> new BannerDuplicateRecipe(CraftingRecipeCategory.MISC), RecipeSerializer.BANNER_DUPLICATE, Items.WHITE_BANNER, 2));
+ recipes.add(RecipeInfo.of(() -> new AddBannerPatternRecipe(CraftingRecipeCategory.MISC), AddBannerPatternRecipe.SERIALIZER, Items.WHITE_BANNER));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_7_2tor1_7_5)) {
+ recipes.add(RecipeInfo.of(() -> new BookCloningRecipe(CraftingRecipeCategory.MISC), RecipeSerializer.BOOK_CLONING, Items.WRITABLE_BOOK, 2));
+ }
+
+ recipes.add(RecipeInfo.shaped(Items.WOODEN_SWORD, "X", "X", "#", '#', Items.STICK, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Items.WOODEN_SHOVEL, "X", "#", "#", '#', Items.STICK, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Items.WOODEN_PICKAXE, "XXX", " # ", " # ", '#', Items.STICK, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Items.WOODEN_HOE, "XX", " #", " #", '#', Items.STICK, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Items.WOODEN_AXE, "XX", "X#", " #", '#', Items.STICK, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Items.STONE_SWORD, "X", "X", "#", '#', Items.STICK, 'X', Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shaped(4, Blocks.COBBLESTONE_STAIRS, "# ", "## ", "###", '#', Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shaped(Items.STONE_SHOVEL, "X", "#", "#", '#', Items.STICK, 'X', Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shaped(Items.STONE_PICKAXE, "XXX", " # ", " # ", '#', Items.STICK, 'X', Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shaped(Items.STONE_HOE, "XX", " #", " #", '#', Items.STICK, 'X', Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shaped(Blocks.STONE_BUTTON, "#", '#', Blocks.STONE));
+ recipes.add(RecipeInfo.shaped(Items.STONE_AXE, "XX", "X#", " #", '#', Items.STICK, 'X', Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shaped(4, Items.STICK, "#", "#", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Blocks.SNOW_BLOCK, "##", "##", '#', Items.SNOWBALL));
+ recipes.add(RecipeInfo.shaped(Blocks.REDSTONE_TORCH, "X", "#", '#', Items.STICK, 'X', Blocks.REDSTONE_WIRE));
+ recipes.add(RecipeInfo.shaped(16, Blocks.RAIL, "X X", "X#X", "X X", '#', Items.STICK, 'X', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(3, Items.PAPER, "###", '#', Blocks.SUGAR_CANE));
+ recipes.add(RecipeInfo.shaped(Items.PAINTING, "###", "#X#", "###", '#', Items.STICK, 'X', Blocks.WHITE_WOOL, Blocks.ORANGE_WOOL, Blocks.MAGENTA_WOOL, Blocks.LIGHT_BLUE_WOOL, Blocks.YELLOW_WOOL, Blocks.LIME_WOOL, Blocks.PINK_WOOL, Blocks.GRAY_WOOL, Blocks.LIGHT_GRAY_WOOL, Blocks.CYAN_WOOL, Blocks.PURPLE_WOOL, Blocks.BLUE_WOOL, Blocks.BROWN_WOOL, Blocks.GREEN_WOOL, Blocks.RED_WOOL, Blocks.BLACK_WOOL));
+ recipes.add(RecipeInfo.shaped("wooden_stairs", 4, Blocks.OAK_STAIRS, "# ", "## ", "###", '#', Blocks.OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("planks", 4, Blocks.OAK_PLANKS, "#", '#', Blocks.OAK_LOG));
+ recipes.add(RecipeInfo.shaped(Items.MINECART, "# #", "###", '#', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Blocks.LEVER, "X", "#", '#', Blocks.COBBLESTONE, 'X', Items.STICK));
+ recipes.add(RecipeInfo.shaped(Items.LEATHER_LEGGINGS, "XXX", "X X", "X X", 'X', Items.LEATHER));
+ recipes.add(RecipeInfo.shaped(Items.LEATHER_HELMET, "XXX", "X X", 'X', Items.LEATHER));
+ recipes.add(RecipeInfo.shaped(Items.LEATHER_CHESTPLATE, "X X", "XXX", "XXX", 'X', Items.LEATHER));
+ recipes.add(RecipeInfo.shaped(Items.LEATHER_BOOTS, "X X", "X X", 'X', Items.LEATHER));
+ recipes.add(RecipeInfo.shaped(Blocks.JUKEBOX, "###", "#X#", "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'X', Items.DIAMOND));
+ recipes.add(RecipeInfo.shaped(Items.IRON_SWORD, "X", "X", "#", '#', Items.STICK, 'X', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.IRON_SHOVEL, "X", "#", "#", '#', Items.STICK, 'X', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.IRON_PICKAXE, "XXX", " # ", " # ", '#', Items.STICK, 'X', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.IRON_LEGGINGS, "XXX", "X X", "X X", 'X', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped("iron_ingot", 9, Items.IRON_INGOT, "#", '#', Blocks.IRON_BLOCK));
+ recipes.add(RecipeInfo.shaped(Items.IRON_HOE, "XX", " #", " #", '#', Items.STICK, 'X', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.IRON_HELMET, "XXX", "X X", 'X', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.IRON_CHESTPLATE, "X X", "XXX", "XXX", 'X', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.IRON_BOOTS, "X X", "X X", 'X', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Blocks.IRON_BLOCK, "###", "###", "###", '#', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.IRON_AXE, "XX", "X#", " #", '#', Items.STICK, 'X', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.GOLDEN_SWORD, "X", "X", "#", '#', Items.STICK, 'X', Items.GOLD_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.GOLDEN_SHOVEL, "X", "#", "#", '#', Items.STICK, 'X', Items.GOLD_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.GOLDEN_PICKAXE, "XXX", " # ", " # ", '#', Items.STICK, 'X', Items.GOLD_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.GOLDEN_LEGGINGS, "XXX", "X X", "X X", 'X', Items.GOLD_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.GOLDEN_HOE, "XX", " #", " #", '#', Items.STICK, 'X', Items.GOLD_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.GOLDEN_HELMET, "XXX", "X X", 'X', Items.GOLD_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.GOLDEN_CHESTPLATE, "X X", "XXX", "XXX", 'X', Items.GOLD_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.GOLDEN_BOOTS, "X X", "X X", 'X', Items.GOLD_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.GOLDEN_AXE, "XX", "X#", " #", '#', Items.STICK, 'X', Items.GOLD_INGOT));
+ recipes.add(RecipeInfo.shaped("gold_ingot", 9, Items.GOLD_INGOT, "#", '#', Blocks.GOLD_BLOCK));
+ recipes.add(RecipeInfo.shaped(Blocks.GOLD_BLOCK, "###", "###", "###", '#', Items.GOLD_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.FURNACE_MINECART, "A", "B", 'A', Blocks.FURNACE, 'B', Items.MINECART));
+ recipes.add(RecipeInfo.shaped(Blocks.FURNACE, "###", "# #", "###", '#', Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shaped(Items.DIAMOND_SWORD, "X", "X", "#", '#', Items.STICK, 'X', Items.DIAMOND));
+ recipes.add(RecipeInfo.shaped(Items.DIAMOND_SHOVEL, "X", "#", "#", '#', Items.STICK, 'X', Items.DIAMOND));
+ recipes.add(RecipeInfo.shaped(Items.DIAMOND_PICKAXE, "XXX", " # ", " # ", '#', Items.STICK, 'X', Items.DIAMOND));
+ recipes.add(RecipeInfo.shaped(Items.DIAMOND_LEGGINGS, "XXX", "X X", "X X", 'X', Items.DIAMOND));
+ recipes.add(RecipeInfo.shaped(Items.DIAMOND_HOE, "XX", " #", " #", '#', Items.STICK, 'X', Items.DIAMOND));
+ recipes.add(RecipeInfo.shaped(Items.DIAMOND_HELMET, "XXX", "X X", 'X', Items.DIAMOND));
+ recipes.add(RecipeInfo.shaped(Items.DIAMOND_CHESTPLATE, "X X", "XXX", "XXX", 'X', Items.DIAMOND));
+ recipes.add(RecipeInfo.shaped(Items.DIAMOND_BOOTS, "X X", "X X", 'X', Items.DIAMOND));
+ recipes.add(RecipeInfo.shaped(Blocks.DIAMOND_BLOCK, "###", "###", "###", '#', Items.DIAMOND));
+ recipes.add(RecipeInfo.shaped(Items.DIAMOND_AXE, "XX", "X#", " #", '#', Items.STICK, 'X', Items.DIAMOND));
+ recipes.add(RecipeInfo.shaped(9, Items.DIAMOND, "#", '#', Blocks.DIAMOND_BLOCK));
+ recipes.add(RecipeInfo.shaped(Blocks.CRAFTING_TABLE, "##", "##", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Blocks.CLAY, "##", "##", '#', Items.CLAY_BALL));
+ recipes.add(RecipeInfo.shaped(Items.CHEST_MINECART, "A", "B", 'A', Blocks.CHEST, 'B', Items.MINECART));
+ recipes.add(RecipeInfo.shaped(Blocks.CHEST, "###", "# #", "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Items.BUCKET, "# #", " # ", '#', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Blocks.BRICKS, "##", "##", '#', Items.BRICK));
+ recipes.add(RecipeInfo.shaped(Items.BREAD, "###", '#', Items.WHEAT));
+ recipes.add(RecipeInfo.shaped(4, Items.BOWL, "# #", " # ", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Items.BOW, " #X", "# X", " #X", '#', Items.STICK, 'X', Blocks.TRIPWIRE));
+ recipes.add(RecipeInfo.shaped(Blocks.BOOKSHELF, "###", "XXX", "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'X', Items.BOOK));
+ recipes.add(RecipeInfo.shaped(4, Items.ARROW, "X", "#", "Y", '#', Items.STICK, 'X', Items.FLINT, 'Y', Items.FEATHER));
+
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_12)) {
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.YELLOW_CONCRETE_POWDER, Items.YELLOW_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.WHITE_CONCRETE_POWDER, Items.BONE_MEAL, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.RED_CONCRETE_POWDER, Items.RED_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.PURPLE_CONCRETE_POWDER, Items.PURPLE_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.PINK_CONCRETE_POWDER, Items.PINK_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.ORANGE_CONCRETE_POWDER, Items.ORANGE_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.MAGENTA_CONCRETE_POWDER, Items.MAGENTA_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.LIME_CONCRETE_POWDER, Items.LIME_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.LIGHT_GRAY_CONCRETE_POWDER, Items.LIGHT_GRAY_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.LIGHT_BLUE_CONCRETE_POWDER, Items.LIGHT_BLUE_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.GREEN_CONCRETE_POWDER, Items.GREEN_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.GRAY_CONCRETE_POWDER, Items.GRAY_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.CYAN_CONCRETE_POWDER, Items.CYAN_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.BROWN_CONCRETE_POWDER, Blocks.COCOA, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.BLUE_CONCRETE_POWDER, Items.LAPIS_LAZULI, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.BLACK_CONCRETE_POWDER, Items.INK_SAC, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.YELLOW_BED, Blocks.WHITE_BED, Items.YELLOW_DYE));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.RED_BED, Blocks.WHITE_BED, Items.RED_DYE));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.PURPLE_BED, Blocks.WHITE_BED, Items.PURPLE_DYE));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.PINK_BED, Blocks.WHITE_BED, Items.PINK_DYE));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.ORANGE_BED, Blocks.WHITE_BED, Items.ORANGE_DYE));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.MAGENTA_BED, Blocks.WHITE_BED, Items.MAGENTA_DYE));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.LIME_BED, Blocks.WHITE_BED, Items.LIME_DYE));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.LIGHT_GRAY_BED, Blocks.WHITE_BED, Items.LIGHT_GRAY_DYE));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.LIGHT_BLUE_BED, Blocks.WHITE_BED, Items.LIGHT_BLUE_DYE));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.GREEN_BED, Blocks.WHITE_BED, Items.GREEN_DYE));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.GRAY_BED, Blocks.WHITE_BED, Items.GRAY_DYE));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.CYAN_BED, Blocks.WHITE_BED, Items.CYAN_DYE));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.BROWN_BED, Blocks.WHITE_BED, Blocks.COCOA));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.BLUE_BED, Blocks.WHITE_BED, Items.LAPIS_LAZULI));
+ recipes.add(RecipeInfo.shapeless("dyed_bed", Blocks.BLACK_BED, Blocks.WHITE_BED, Items.INK_SAC));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.YELLOW_BED, "###", "XXX", '#', Blocks.YELLOW_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.WHITE_BED, "###", "XXX", '#', Blocks.WHITE_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.RED_BED, "###", "XXX", '#', Blocks.RED_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.PURPLE_BED, "###", "XXX", '#', Blocks.PURPLE_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.PINK_BED, "###", "XXX", '#', Blocks.PINK_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.ORANGE_BED, "###", "XXX", '#', Blocks.ORANGE_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.MAGENTA_BED, "###", "XXX", '#', Blocks.MAGENTA_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.LIME_BED, "###", "XXX", '#', Blocks.LIME_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.LIGHT_GRAY_BED, "###", "XXX", '#', Blocks.LIGHT_GRAY_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.LIGHT_BLUE_BED, "###", "XXX", '#', Blocks.LIGHT_BLUE_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.GREEN_BED, "###", "XXX", '#', Blocks.GREEN_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.GRAY_BED, "###", "XXX", '#', Blocks.GRAY_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.CYAN_BED, "###", "XXX", '#', Blocks.CYAN_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.BROWN_BED, "###", "XXX", '#', Blocks.BROWN_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.BLUE_BED, "###", "XXX", '#', Blocks.BLUE_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("bed", Blocks.BLACK_BED, "###", "XXX", '#', Blocks.BLACK_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ } else {
+ recipes.add(RecipeInfo.shapeless(Blocks.WHITE_WOOL, Blocks.WHITE_WOOL, Items.BONE_MEAL));
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_3tob1_3_1)) {
+ recipes.add(RecipeInfo.shaped("bed", Blocks.RED_BED, "###", "XXX", '#', Blocks.YELLOW_WOOL, Blocks.BLACK_WOOL, Blocks.BLUE_WOOL, Blocks.BROWN_WOOL, Blocks.CYAN_WOOL, Blocks.GRAY_WOOL, Blocks.GREEN_WOOL, Blocks.LIGHT_BLUE_WOOL, Blocks.LIGHT_GRAY_WOOL, Blocks.WHITE_WOOL, Blocks.RED_WOOL, Blocks.PURPLE_WOOL, Blocks.PINK_WOOL, Blocks.ORANGE_WOOL, Blocks.LIME_WOOL, Blocks.MAGENTA_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ }
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_11_1to1_11_2)) {
+ recipes.add(RecipeInfo.shaped(9, Items.IRON_NUGGET, "#", '#', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped("iron_ingot", Items.IRON_INGOT, "###", "###", "###", '#', Items.IRON_NUGGET).distinguisher("iron_nugget_to_ingot"));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_11)) {
+ recipes.add(RecipeInfo.shaped(Blocks.OBSERVER, "###", "RRQ", "###", 'Q', Items.QUARTZ, 'R', Blocks.REDSTONE_WIRE, '#', Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shaped(Blocks.PURPLE_SHULKER_BOX, "-", "#", "-", '#', Blocks.CHEST, '-', Items.SHULKER_SHELL));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_10)) {
+ recipes.add(RecipeInfo.shapeless("bonemeal", 9, Items.BONE_MEAL, Blocks.BONE_BLOCK));
+ recipes.add(RecipeInfo.shaped(Blocks.BONE_BLOCK, "XXX", "XXX", "XXX", 'X', Items.BONE_MEAL));
+ recipes.add(RecipeInfo.shaped(Blocks.MAGMA_BLOCK, "##", "##", '#', Items.MAGMA_CREAM));
+ recipes.add(RecipeInfo.shaped(Blocks.NETHER_WART_BLOCK, "###", "###", "###", '#', Blocks.NETHER_WART));
+ recipes.add(RecipeInfo.shaped(Blocks.RED_NETHER_BRICKS, "NW", "WN", 'W', Blocks.NETHER_WART, 'N', Items.NETHER_BRICK));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_9)) {
+ recipes.add(RecipeInfo.shapeless(Blocks.TRAPPED_CHEST, Blocks.CHEST, Blocks.TRIPWIRE_HOOK));
+ recipes.add(RecipeInfo.shaped(Items.SHIELD, "WoW", "WWW", " W ", 'W', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'o', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(4, Blocks.PURPUR_BLOCK, "FF", "FF", 'F', Items.POPPED_CHORUS_FRUIT));
+ recipes.add(RecipeInfo.shaped(6, Blocks.PURPUR_SLAB, "###", '#', Blocks.PURPUR_BLOCK));
+ recipes.add(RecipeInfo.shaped(4, Blocks.PURPUR_STAIRS, "# ", "## ", "###", '#', Blocks.PURPUR_BLOCK));
+ recipes.add(RecipeInfo.shaped(Blocks.PURPUR_PILLAR, "#", "#", '#', Blocks.PURPUR_SLAB));
+ recipes.add(RecipeInfo.shaped(4, Blocks.END_STONE_BRICKS, "##", "##", '#', Blocks.END_STONE));
+ recipes.add(RecipeInfo.shaped("boat", Items.SPRUCE_BOAT, "# #", "###", '#', Blocks.SPRUCE_PLANKS));
+ recipes.add(RecipeInfo.shaped("boat", Items.JUNGLE_BOAT, "# #", "###", '#', Blocks.JUNGLE_PLANKS));
+ recipes.add(RecipeInfo.shaped("boat", Items.OAK_BOAT, "# #", "###", '#', Blocks.OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("boat", Items.DARK_OAK_BOAT, "# #", "###", '#', Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("boat", Items.BIRCH_BOAT, "# #", "###", '#', Blocks.BIRCH_PLANKS));
+ recipes.add(RecipeInfo.shaped("boat", Items.ACACIA_BOAT, "# #", "###", '#', Blocks.ACACIA_PLANKS));
+ recipes.add(RecipeInfo.shaped(4, Blocks.END_ROD, "/", "#", '#', Items.POPPED_CHORUS_FRUIT, '/', Items.BLAZE_ROD));
+ recipes.add(RecipeInfo.shaped(Items.END_CRYSTAL, "GGG", "GEG", "GTG", 'T', Items.GHAST_TEAR, 'E', Items.ENDER_EYE, 'G', Blocks.GLASS));
+ recipes.add(RecipeInfo.shaped(2, Items.SPECTRAL_ARROW, " # ", "#X#", " # ", '#', Items.GLOWSTONE_DUST, 'X', Items.ARROW));
+ recipes.add(RecipeInfo.shapeless("red_dye", Items.RED_DYE, Items.BEETROOT));
+ recipes.add(RecipeInfo.shaped(Items.BEETROOT_SOUP, "OOO", "OOO", " B ", 'B', Items.BOWL, 'O', Items.BEETROOT));
+ } else {
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_5tor1_5_1)) {
+ recipes.add(RecipeInfo.shaped(Blocks.TRAPPED_CHEST, "#-", '#', Blocks.CHEST, '-', Blocks.TRIPWIRE_HOOK));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_3_1tor1_3_2)) {
+ recipes.add(RecipeInfo.shaped(Items.ENCHANTED_GOLDEN_APPLE, "###", "#X#", "###", '#', Items.GOLD_BLOCK, 'X', Items.APPLE));
+ }
+ recipes.add(RecipeInfo.shaped("boat", Items.OAK_BOAT, "# #", "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.DARK_OAK_PLANKS, Blocks.BIRCH_PLANKS, Blocks.ACACIA_PLANKS));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_8)) {
+ recipes.add(RecipeInfo.shapeless(Blocks.MOSSY_COBBLESTONE, Blocks.COBBLESTONE, Blocks.VINE));
+ recipes.add(RecipeInfo.shapeless(Blocks.MOSSY_STONE_BRICKS, Blocks.STONE_BRICKS, Blocks.VINE));
+ recipes.add(RecipeInfo.shaped(Blocks.CHISELED_STONE_BRICKS, "#", "#", '#', Blocks.STONE_BRICK_SLAB));
+ recipes.add(RecipeInfo.shaped(4, Blocks.COARSE_DIRT, "DG", "GD", 'D', Blocks.DIRT, 'G', Blocks.GRAVEL));
+ recipes.add(RecipeInfo.shaped("wooden_fence", 3, Blocks.SPRUCE_FENCE, "W#W", "W#W", '#', Items.STICK, 'W', Blocks.SPRUCE_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_fence", 3, Blocks.JUNGLE_FENCE, "W#W", "W#W", '#', Items.STICK, 'W', Blocks.JUNGLE_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_fence", 3, Blocks.OAK_FENCE, "W#W", "W#W", '#', Items.STICK, 'W', Blocks.OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_fence", 3, Blocks.DARK_OAK_FENCE, "W#W", "W#W", '#', Items.STICK, 'W', Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_fence", 3, Blocks.BIRCH_FENCE, "W#W", "W#W", '#', Items.STICK, 'W', Blocks.BIRCH_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_fence", 3, Blocks.ACACIA_FENCE, "W#W", "W#W", '#', Items.STICK, 'W', Blocks.ACACIA_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_fence_gate", Blocks.SPRUCE_FENCE_GATE, "#W#", "#W#", '#', Items.STICK, 'W', Blocks.SPRUCE_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_fence_gate", Blocks.JUNGLE_FENCE_GATE, "#W#", "#W#", '#', Items.STICK, 'W', Blocks.JUNGLE_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_fence_gate", Blocks.OAK_FENCE_GATE, "#W#", "#W#", '#', Items.STICK, 'W', Blocks.OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_fence_gate", Blocks.DARK_OAK_FENCE_GATE, "#W#", "#W#", '#', Items.STICK, 'W', Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_fence_gate", Blocks.BIRCH_FENCE_GATE, "#W#", "#W#", '#', Items.STICK, 'W', Blocks.BIRCH_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_fence_gate", Blocks.ACACIA_FENCE_GATE, "#W#", "#W#", '#', Items.STICK, 'W', Blocks.ACACIA_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_door", 3, Blocks.OAK_DOOR, "##", "##", "##", '#', Blocks.OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_door", 3, Blocks.SPRUCE_DOOR, "##", "##", "##", '#', Blocks.SPRUCE_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_door", 3, Blocks.JUNGLE_DOOR, "##", "##", "##", '#', Blocks.JUNGLE_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_door", 3, Blocks.DARK_OAK_DOOR, "##", "##", "##", '#', Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_door", 3, Blocks.BIRCH_DOOR, "##", "##", "##", '#', Blocks.BIRCH_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_door", 3, Blocks.ACACIA_DOOR, "##", "##", "##", '#', Blocks.ACACIA_PLANKS));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.YELLOW_BANNER, "###", "###", " | ", '#', Blocks.YELLOW_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.RED_BANNER, "###", "###", " | ", '#', Blocks.RED_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.PURPLE_BANNER, "###", "###", " | ", '#', Blocks.PURPLE_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.PINK_BANNER, "###", "###", " | ", '#', Blocks.PINK_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.ORANGE_BANNER, "###", "###", " | ", '#', Blocks.ORANGE_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.MAGENTA_BANNER, "###", "###", " | ", '#', Blocks.MAGENTA_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.LIME_BANNER, "###", "###", " | ", '#', Blocks.LIME_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.LIGHT_GRAY_BANNER, "###", "###", " | ", '#', Blocks.LIGHT_GRAY_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.LIGHT_BLUE_BANNER, "###", "###", " | ", '#', Blocks.LIGHT_BLUE_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.GREEN_BANNER, "###", "###", " | ", '#', Blocks.GREEN_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.GRAY_BANNER, "###", "###", " | ", '#', Blocks.GRAY_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.CYAN_BANNER, "###", "###", " | ", '#', Blocks.CYAN_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.BROWN_BANNER, "###", "###", " | ", '#', Blocks.BROWN_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.BLUE_BANNER, "###", "###", " | ", '#', Blocks.BLUE_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.BLACK_BANNER, "###", "###", " | ", '#', Blocks.BLACK_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("banner", Blocks.WHITE_BANNER, "###", "###", " | ", '#', Blocks.WHITE_WOOL, '|', Items.STICK));
+ recipes.add(RecipeInfo.shaped("rabbit_stew", Items.RABBIT_STEW, " R ", "CPD", " B ", 'P', Items.BAKED_POTATO, 'R', Items.COOKED_RABBIT, 'B', Items.BOWL, 'C', Blocks.CARROTS, 'D', Blocks.RED_MUSHROOM));
+ recipes.add(RecipeInfo.shaped("rabbit_stew", Items.RABBIT_STEW, " R ", "CPM", " B ", 'P', Items.BAKED_POTATO, 'R', Items.COOKED_RABBIT, 'B', Items.BOWL, 'C', Blocks.CARROTS, 'M', Blocks.BROWN_MUSHROOM));
+ recipes.add(RecipeInfo.shaped(3, Blocks.IRON_DOOR, "##", "##", "##", '#', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Blocks.IRON_TRAPDOOR, "##", "##", '#', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Blocks.RED_SANDSTONE, "##", "##", '#', Blocks.RED_SAND));
+ recipes.add(RecipeInfo.shaped(4, Blocks.CUT_RED_SANDSTONE, "##", "##", '#', Blocks.RED_SANDSTONE));
+ recipes.add(RecipeInfo.shaped(6, Blocks.RED_SANDSTONE_SLAB, "###", '#', Blocks.RED_SANDSTONE, Blocks.CHISELED_RED_SANDSTONE, Blocks.CUT_RED_SANDSTONE));
+ recipes.add(RecipeInfo.shaped(4, Blocks.RED_SANDSTONE_STAIRS, "# ", "## ", "###", '#', Blocks.RED_SANDSTONE, Blocks.CHISELED_RED_SANDSTONE, Blocks.CUT_RED_SANDSTONE));
+ recipes.add(RecipeInfo.shaped(Blocks.CHISELED_RED_SANDSTONE, "#", "#", '#', Blocks.RED_SANDSTONE_SLAB));
+ recipes.add(RecipeInfo.shaped(Items.LEATHER, "##", "##", '#', Items.RABBIT_HIDE));
+ recipes.add(RecipeInfo.shaped(Items.ARMOR_STAND, "///", " / ", "/_/", '/', Items.STICK, '_', Blocks.SMOOTH_STONE_SLAB));
+ recipes.add(RecipeInfo.shaped(Blocks.SEA_LANTERN, "SCS", "CCC", "SCS", 'S', Items.PRISMARINE_SHARD, 'C', Items.PRISMARINE_CRYSTALS));
+ recipes.add(RecipeInfo.shaped(Blocks.PRISMARINE_BRICKS, "SSS", "SSS", "SSS", 'S', Items.PRISMARINE_SHARD));
+ recipes.add(RecipeInfo.shaped(Blocks.PRISMARINE, "SS", "SS", 'S', Items.PRISMARINE_SHARD));
+ recipes.add(RecipeInfo.shaped(Blocks.DARK_PRISMARINE, "SSS", "SIS", "SSS", 'S', Items.PRISMARINE_SHARD, 'I', Items.INK_SAC));
+ recipes.add(RecipeInfo.shaped(9, Items.SLIME_BALL, "#", '#', Blocks.SLIME_BLOCK));
+ recipes.add(RecipeInfo.shaped(Blocks.SLIME_BLOCK, "###", "###", "###", '#', Items.SLIME_BALL));
+ recipes.add(RecipeInfo.shaped(2, Blocks.DIORITE, "CQ", "QC", 'Q', Items.QUARTZ, 'C', Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shapeless(2, Blocks.ANDESITE, Blocks.DIORITE, Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shapeless(Blocks.GRANITE, Blocks.DIORITE, Items.QUARTZ));
+ recipes.add(RecipeInfo.shaped(4, Blocks.POLISHED_GRANITE, "SS", "SS", 'S', Blocks.GRANITE));
+ recipes.add(RecipeInfo.shaped(4, Blocks.POLISHED_DIORITE, "SS", "SS", 'S', Blocks.DIORITE));
+ recipes.add(RecipeInfo.shaped(4, Blocks.POLISHED_ANDESITE, "SS", "SS", 'S', Blocks.ANDESITE));
+ } else {
+ recipes.add(RecipeInfo.shaped("wooden_fence", 2, Blocks.OAK_FENCE, "###", "###", '#', Items.STICK));
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_8tob1_8_1)) {
+ recipes.add(RecipeInfo.shaped("wooden_fence_gate", Blocks.OAK_FENCE_GATE, "#W#", "#W#", '#', Items.STICK, 'W', Blocks.OAK_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.DARK_OAK_PLANKS, Blocks.BIRCH_PLANKS, Blocks.ACACIA_PLANKS));
+ }
+ recipes.add(RecipeInfo.shaped(Blocks.IRON_DOOR, "##", "##", "##", '#', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped("wooden_door", Blocks.OAK_DOOR, "##", "##", "##", '#', Blocks.OAK_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.DARK_OAK_PLANKS, Blocks.BIRCH_PLANKS, Blocks.ACACIA_PLANKS));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_7_2tor1_7_5)) {
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.YELLOW_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.YELLOW_DYE));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.WHITE_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.BONE_MEAL));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.RED_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.RED_DYE));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.PURPLE_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.PURPLE_DYE));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.PINK_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.PINK_DYE));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.ORANGE_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.ORANGE_DYE));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.MAGENTA_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.MAGENTA_DYE));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.LIME_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.LIME_DYE));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.LIGHT_GRAY_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.LIGHT_GRAY_DYE));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.LIGHT_BLUE_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.LIGHT_BLUE_DYE));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.GREEN_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.GREEN_DYE));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.GRAY_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.GRAY_DYE));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.CYAN_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.CYAN_DYE));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.BROWN_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Blocks.COCOA));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.BLUE_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.LAPIS_LAZULI));
+ recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.BLACK_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.INK_SAC));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.YELLOW_STAINED_GLASS_PANE, "###", "###", '#', Blocks.YELLOW_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.WHITE_STAINED_GLASS_PANE, "###", "###", '#', Blocks.WHITE_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.RED_STAINED_GLASS_PANE, "###", "###", '#', Blocks.RED_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.PURPLE_STAINED_GLASS_PANE, "###", "###", '#', Blocks.PURPLE_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.PINK_STAINED_GLASS_PANE, "###", "###", '#', Blocks.PINK_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.ORANGE_STAINED_GLASS_PANE, "###", "###", '#', Blocks.ORANGE_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.MAGENTA_STAINED_GLASS_PANE, "###", "###", '#', Blocks.MAGENTA_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.LIME_STAINED_GLASS_PANE, "###", "###", '#', Blocks.LIME_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.LIGHT_GRAY_STAINED_GLASS_PANE, "###", "###", '#', Blocks.LIGHT_GRAY_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.LIGHT_BLUE_STAINED_GLASS_PANE, "###", "###", '#', Blocks.LIGHT_BLUE_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.GREEN_STAINED_GLASS_PANE, "###", "###", '#', Blocks.GREEN_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.GRAY_STAINED_GLASS_PANE, "###", "###", '#', Blocks.GRAY_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.CYAN_STAINED_GLASS_PANE, "###", "###", '#', Blocks.CYAN_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.BROWN_STAINED_GLASS_PANE, "###", "###", '#', Blocks.BROWN_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.BLUE_STAINED_GLASS_PANE, "###", "###", '#', Blocks.BLUE_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("stained_glass_pane", 16, Blocks.BLACK_STAINED_GLASS_PANE, "###", "###", '#', Blocks.BLACK_STAINED_GLASS));
+ recipes.add(RecipeInfo.shaped("planks", 4, Blocks.ACACIA_PLANKS, "#", '#', Blocks.ACACIA_LOG));
+ recipes.add(RecipeInfo.shaped("planks", 4, Blocks.DARK_OAK_PLANKS, "#", '#', Blocks.DARK_OAK_LOG));
+ recipes.add(RecipeInfo.shaped("wooden_slab", 6, Blocks.ACACIA_SLAB, "###", '#', Blocks.ACACIA_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_stairs", 4, Blocks.ACACIA_STAIRS, "# ", "## ", "###", '#', Blocks.ACACIA_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_slab", 6, Blocks.DARK_OAK_SLAB, "###", '#', Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_stairs", 4, Blocks.DARK_OAK_STAIRS, "# ", "## ", "###", '#', Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Blocks.TNT, "X#X", "#X#", "X#X", '#', Blocks.SAND, Blocks.RED_SAND, 'X', Items.GUNPOWDER));
+ recipes.add(RecipeInfo.shapeless("red_dye", Items.RED_DYE, Blocks.RED_TULIP));
+ recipes.add(RecipeInfo.shapeless("orange_dye", Items.ORANGE_DYE, Blocks.ORANGE_TULIP));
+ recipes.add(RecipeInfo.shapeless("light_gray_dye", Items.LIGHT_GRAY_DYE, Blocks.WHITE_TULIP));
+ recipes.add(RecipeInfo.shapeless("pink_dye", Items.PINK_DYE, Blocks.PINK_TULIP));
+ recipes.add(RecipeInfo.shapeless("light_blue_dye", Items.LIGHT_BLUE_DYE, Blocks.BLUE_ORCHID));
+ recipes.add(RecipeInfo.shapeless("magenta_dye", Items.MAGENTA_DYE, Blocks.ALLIUM));
+ recipes.add(RecipeInfo.shapeless("light_gray_dye", Items.LIGHT_GRAY_DYE, Blocks.AZURE_BLUET));
+ recipes.add(RecipeInfo.shapeless("light_gray_dye", Items.LIGHT_GRAY_DYE, Blocks.OXEYE_DAISY));
+ recipes.add(RecipeInfo.shapeless("yellow_dye", 2, Items.YELLOW_DYE, Blocks.SUNFLOWER));
+ recipes.add(RecipeInfo.shapeless("pink_dye", 2, Items.PINK_DYE, Blocks.PEONY));
+ recipes.add(RecipeInfo.shapeless("red_dye", 2, Items.RED_DYE, Blocks.ROSE_BUSH));
+ recipes.add(RecipeInfo.shapeless("magenta_dye", 2, Items.MAGENTA_DYE, Blocks.LILAC));
+ recipes.add(RecipeInfo.shapeless(Items.FLINT_AND_STEEL, Items.IRON_INGOT, Items.FLINT));
+ } else {
+ recipes.add(RecipeInfo.shaped(Items.FLINT_AND_STEEL, "A ", " B", 'A', Items.IRON_INGOT, 'B', Items.FLINT));
+ recipes.add(RecipeInfo.shaped(Blocks.TNT, "X#X", "#X#", "X#X", '#', Blocks.SAND, 'X', Items.GUNPOWDER));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_6_1)) {
+ recipes.add(RecipeInfo.shaped(Items.GOLDEN_APPLE, "###", "#X#", "###", '#', Items.GOLD_INGOT, 'X', Items.APPLE));
+ recipes.add(RecipeInfo.shaped(Items.GLISTERING_MELON_SLICE, "###", "#X#", "###", '#', Items.GOLD_NUGGET, 'X', Items.MELON_SLICE));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.YELLOW_CARPET, "##", '#', Blocks.YELLOW_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.WHITE_CARPET, "##", '#', Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.RED_CARPET, "##", '#', Blocks.RED_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.PURPLE_CARPET, "##", '#', Blocks.PURPLE_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.PINK_CARPET, "##", '#', Blocks.PINK_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.ORANGE_CARPET, "##", '#', Blocks.ORANGE_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.MAGENTA_CARPET, "##", '#', Blocks.MAGENTA_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.LIME_CARPET, "##", '#', Blocks.LIME_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.LIGHT_GRAY_CARPET, "##", '#', Blocks.LIGHT_GRAY_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.LIGHT_BLUE_CARPET, "##", '#', Blocks.LIGHT_BLUE_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.GREEN_CARPET, "##", '#', Blocks.GREEN_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.GRAY_CARPET, "##", '#', Blocks.GRAY_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.CYAN_CARPET, "##", '#', Blocks.CYAN_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.BROWN_CARPET, "##", '#', Blocks.BROWN_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.BLUE_CARPET, "##", '#', Blocks.BLUE_WOOL));
+ recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.BLACK_CARPET, "##", '#', Blocks.BLACK_WOOL));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.YELLOW_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.YELLOW_DYE));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.WHITE_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.BONE_MEAL));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.RED_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.RED_DYE));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.PURPLE_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.PURPLE_DYE));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.PINK_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.PINK_DYE));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.ORANGE_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.ORANGE_DYE));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.MAGENTA_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.MAGENTA_DYE));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.LIME_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.LIME_DYE));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.LIGHT_GRAY_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.LIGHT_GRAY_DYE));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.LIGHT_BLUE_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.LIGHT_BLUE_DYE));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.GREEN_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.GREEN_DYE));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.GRAY_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.GRAY_DYE));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.CYAN_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.CYAN_DYE));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.BROWN_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Blocks.COCOA));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.BLUE_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.LAPIS_LAZULI));
+ recipes.add(RecipeInfo.shaped("stained_hardened_clay", 8, Blocks.BLACK_TERRACOTTA, "###", "#X#", "###", '#', Blocks.TERRACOTTA, 'X', Items.INK_SAC));
+ recipes.add(RecipeInfo.shaped(2, Items.LEAD, "~~ ", "~O ", " ~", '~', Blocks.TRIPWIRE, 'O', Items.SLIME_BALL));
+ recipes.add(RecipeInfo.shaped(Blocks.HAY_BLOCK, "###", "###", "###", '#', Items.WHEAT));
+ recipes.add(RecipeInfo.shaped(9, Items.WHEAT, "#", '#', Blocks.HAY_BLOCK));
+ recipes.add(RecipeInfo.shaped(Blocks.COAL_BLOCK, "###", "###", "###", '#', Items.COAL));
+ recipes.add(RecipeInfo.shaped(9, Items.COAL, "#", '#', Blocks.COAL_BLOCK));
+ } else {
+ recipes.add(RecipeInfo.shaped(Items.GOLDEN_APPLE, "###", "#X#", "###", '#', Items.GOLD_NUGGET, 'X', Items.APPLE));
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_0_0tor1_0_1)) {
+ recipes.add(RecipeInfo.shapeless(Items.GLISTERING_MELON_SLICE, Items.GOLD_NUGGET, Items.MELON_SLICE));
+ }
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_5tor1_5_1)) {
+ recipes.add(RecipeInfo.shaped(6, Blocks.SNOW, "###", '#', Blocks.SNOW_BLOCK));
+ recipes.add(RecipeInfo.shaped(Blocks.QUARTZ_BLOCK, "##", "##", '#', Items.QUARTZ));
+ recipes.add(RecipeInfo.shaped(2, Blocks.QUARTZ_PILLAR, "#", "#", '#', Blocks.QUARTZ_BLOCK));
+ recipes.add(RecipeInfo.shaped(Blocks.CHISELED_QUARTZ_BLOCK, "#", "#", '#', Blocks.QUARTZ_SLAB));
+ recipes.add(RecipeInfo.shaped(6, Blocks.QUARTZ_SLAB, "###", '#', Blocks.QUARTZ_BLOCK, Blocks.CHISELED_QUARTZ_BLOCK, Blocks.QUARTZ_PILLAR));
+ recipes.add(RecipeInfo.shaped(6, Blocks.ACTIVATOR_RAIL, "XSX", "X#X", "XSX", '#', Blocks.REDSTONE_TORCH, 'S', Items.STICK, 'X', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.TNT_MINECART, "A", "B", 'A', Blocks.TNT, 'B', Items.MINECART));
+ recipes.add(RecipeInfo.shaped(Items.HOPPER_MINECART, "A", "B", 'A', Blocks.HOPPER, 'B', Items.MINECART));
+ recipes.add(RecipeInfo.shaped(4, Blocks.QUARTZ_STAIRS, "# ", "## ", "###", '#', Blocks.QUARTZ_BLOCK, Blocks.CHISELED_QUARTZ_BLOCK, Blocks.QUARTZ_PILLAR));
+ recipes.add(RecipeInfo.shaped(Blocks.COMPARATOR, " # ", "#X#", "III", '#', Blocks.REDSTONE_TORCH, 'X', Items.QUARTZ, 'I', Blocks.STONE));
+ recipes.add(RecipeInfo.shaped(Blocks.LIGHT_WEIGHTED_PRESSURE_PLATE, "##", '#', Items.GOLD_INGOT));
+ recipes.add(RecipeInfo.shaped(Blocks.HEAVY_WEIGHTED_PRESSURE_PLATE, "##", '#', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Blocks.DROPPER, "###", "# #", "#R#", 'R', Blocks.REDSTONE_WIRE, '#', Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shaped(Blocks.HOPPER, "I I", "ICI", " I ", 'C', Blocks.CHEST, 'I', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Blocks.NETHER_BRICKS, "NN", "NN", 'N', Items.NETHER_BRICK));
+ recipes.add(RecipeInfo.shaped(Blocks.DAYLIGHT_DETECTOR, "GGG", "QQQ", "WWW", 'Q', Items.QUARTZ, 'G', Blocks.GLASS, 'W', Blocks.OAK_SLAB, Blocks.SPRUCE_SLAB, Blocks.BIRCH_SLAB, Blocks.JUNGLE_SLAB, Blocks.ACACIA_SLAB, Blocks.DARK_OAK_SLAB));
+ recipes.add(RecipeInfo.shaped(Blocks.REDSTONE_BLOCK, "###", "###", "###", '#', Blocks.REDSTONE_WIRE));
+ recipes.add(RecipeInfo.shaped(9, Blocks.REDSTONE_WIRE, "#", '#', Blocks.REDSTONE_BLOCK));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_4_6tor1_4_7)) {
+ recipes.add(RecipeInfo.shaped(6, Blocks.NETHER_BRICK_SLAB, "###", '#', Blocks.NETHER_BRICKS));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_4_2)) {
+ recipes.add(RecipeInfo.shaped(6, Blocks.COBBLESTONE_WALL, "###", "###", '#', Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shaped(6, Blocks.MOSSY_COBBLESTONE_WALL, "###", "###", '#', Blocks.MOSSY_COBBLESTONE));
+ recipes.add(RecipeInfo.shaped(Blocks.FLOWER_POT, "# #", " # ", '#', Items.BRICK));
+ recipes.add(RecipeInfo.shaped(Items.CARROT_ON_A_STICK, "# ", " X", '#', Items.FISHING_ROD, 'X', Blocks.CARROTS));
+ recipes.add(RecipeInfo.shaped(Items.ITEM_FRAME, "###", "#X#", "###", '#', Items.STICK, 'X', Items.LEATHER));
+ recipes.add(RecipeInfo.shaped(Items.GOLDEN_CARROT, "###", "#X#", "###", '#', Items.GOLD_NUGGET, 'X', Blocks.CARROTS));
+ recipes.add(RecipeInfo.shaped(Blocks.OAK_BUTTON, "#", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Blocks.ANVIL, "III", " i ", "iii", 'I', Blocks.IRON_BLOCK, 'i', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Blocks.BEACON, "GGG", "GSG", "OOO", 'S', Items.NETHER_STAR, 'G', Blocks.GLASS, 'O', Blocks.OBSIDIAN));
+ recipes.add(RecipeInfo.shapeless(Items.PUMPKIN_PIE, Blocks.CARVED_PUMPKIN, Items.SUGAR, Items.EGG));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_3_1tor1_3_2)) {
+ recipes.add(RecipeInfo.shapeless(Items.WRITABLE_BOOK, Items.BOOK, Items.INK_SAC, Items.FEATHER));
+ recipes.add(RecipeInfo.shapeless(Items.BOOK, Items.PAPER, Items.PAPER, Items.PAPER, Items.LEATHER));
+ recipes.add(RecipeInfo.shaped(3, Blocks.OAK_SIGN, "###", "###", " X ", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'X', Items.STICK));
+ recipes.add(RecipeInfo.shaped("wooden_slab", 6, Blocks.SPRUCE_SLAB, "###", '#', Blocks.SPRUCE_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_slab", 6, Blocks.BIRCH_SLAB, "###", '#', Blocks.BIRCH_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_slab", 6, Blocks.JUNGLE_SLAB, "###", '#', Blocks.JUNGLE_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_slab", 6, Blocks.OAK_SLAB, "###", '#', Blocks.OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_stairs", 4, Blocks.SPRUCE_STAIRS, "# ", "## ", "###", '#', Blocks.SPRUCE_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_stairs", 4, Blocks.BIRCH_STAIRS, "# ", "## ", "###", '#', Blocks.BIRCH_PLANKS));
+ recipes.add(RecipeInfo.shaped("wooden_stairs", 4, Blocks.JUNGLE_STAIRS, "# ", "## ", "###", '#', Blocks.JUNGLE_PLANKS));
+ recipes.add(RecipeInfo.shaped(4, Blocks.SANDSTONE_STAIRS, "# ", "## ", "###", '#', Blocks.SANDSTONE, Blocks.CHISELED_SANDSTONE, Blocks.CUT_SANDSTONE));
+ recipes.add(RecipeInfo.shaped(2, Blocks.TRIPWIRE_HOOK, "I", "S", "#", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'S', Items.STICK, 'I', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Blocks.ENDER_CHEST, "###", "#E#", "###", '#', Blocks.OBSIDIAN, 'E', Items.ENDER_EYE));
+ recipes.add(RecipeInfo.shaped(Blocks.EMERALD_BLOCK, "###", "###", "###", '#', Items.EMERALD));
+ recipes.add(RecipeInfo.shaped(9, Items.EMERALD, "#", '#', Blocks.EMERALD_BLOCK));
+ } else {
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_2_1tor1_2_3)) {
+ recipes.add(RecipeInfo.shaped("wooden_slab", 6, Blocks.OAK_SLAB, "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ } else {
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_3tob1_3_1)) {
+ recipes.add(RecipeInfo.shaped("wooden_slab", 3, Blocks.OAK_SLAB, "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ }
+ }
+ recipes.add(RecipeInfo.shaped(Items.BOOK, "#", "#", "#", '#', Items.PAPER));
+ recipes.add(RecipeInfo.shaped(Blocks.OAK_SIGN, "###", "###", " X ", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'X', Items.STICK));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_2_4tor1_2_5)) {
+ recipes.add(RecipeInfo.shaped("planks", 4, Blocks.BIRCH_PLANKS, "#", '#', Blocks.BIRCH_LOG));
+ recipes.add(RecipeInfo.shaped("planks", 4, Blocks.SPRUCE_PLANKS, "#", '#', Blocks.SPRUCE_LOG));
+ recipes.add(RecipeInfo.shaped("planks", 4, Blocks.JUNGLE_PLANKS, "#", '#', Blocks.JUNGLE_LOG));
+ recipes.add(RecipeInfo.shaped(Blocks.CHISELED_SANDSTONE, "#", "#", '#', Blocks.SANDSTONE_SLAB));
+ recipes.add(RecipeInfo.shaped(4, Blocks.CUT_SANDSTONE, "##", "##", '#', Blocks.SANDSTONE));
+ } else {
+ recipes.add(RecipeInfo.shaped("planks", 4, Blocks.OAK_PLANKS, "#", '#', Blocks.BIRCH_LOG, Blocks.SPRUCE_LOG, Blocks.JUNGLE_LOG));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_2_1tor1_2_3)) {
+ recipes.add(RecipeInfo.shaped(3, Blocks.LADDER, "# #", "###", "# #", '#', Items.STICK));
+ recipes.add(RecipeInfo.shaped(6, Blocks.SMOOTH_STONE_SLAB, "###", '#', Blocks.STONE));
+ recipes.add(RecipeInfo.shaped(6, Blocks.SANDSTONE_SLAB, "###", '#', Blocks.SANDSTONE, Blocks.CHISELED_SANDSTONE, Blocks.CUT_SANDSTONE));
+ recipes.add(RecipeInfo.shaped(6, Blocks.COBBLESTONE_SLAB, "###", '#', Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shaped(6, Blocks.BRICK_SLAB, "###", '#', Blocks.BRICKS));
+ recipes.add(RecipeInfo.shaped(6, Blocks.STONE_BRICK_SLAB, "###", '#', Blocks.STONE_BRICKS, Blocks.MOSSY_STONE_BRICKS, Blocks.CRACKED_STONE_BRICKS, Blocks.CHISELED_STONE_BRICKS));
+ recipes.add(RecipeInfo.shaped(Blocks.REDSTONE_LAMP, " R ", "RGR", " R ", 'R', Blocks.REDSTONE_WIRE, 'G', Blocks.GLOWSTONE));
+ recipes.add(RecipeInfo.shapeless(3, Items.FIRE_CHARGE, new ItemConvertible[]{Items.GUNPOWDER}, new ItemConvertible[]{Items.BLAZE_POWDER}, new ItemConvertible[]{Items.COAL, Items.CHARCOAL}));
+ } else {
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_5tob1_5_2)) {
+ recipes.add(RecipeInfo.shaped(2, Blocks.LADDER, "# #", "###", "# #", '#', Items.STICK));
+ } else {
+ recipes.add(RecipeInfo.shaped(1, Blocks.LADDER, "# #", "###", "# #", '#', Items.STICK));
+ }
+ recipes.add(RecipeInfo.shaped(3, Blocks.SMOOTH_STONE_SLAB, "###", '#', Blocks.STONE));
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_3tob1_3_1)) {
+ recipes.add(RecipeInfo.shaped(3, Blocks.SANDSTONE_SLAB, "###", '#', Blocks.SANDSTONE, Blocks.CHISELED_SANDSTONE, Blocks.CUT_SANDSTONE));
+ recipes.add(RecipeInfo.shaped(3, Blocks.COBBLESTONE_SLAB, "###", '#', Blocks.COBBLESTONE));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_8tob1_8_1)) {
+ recipes.add(RecipeInfo.shaped(3, Blocks.BRICK_SLAB, "###", '#', Blocks.BRICKS));
+ recipes.add(RecipeInfo.shaped(3, Blocks.STONE_BRICK_SLAB, "###", '#', Blocks.STONE_BRICKS, Blocks.MOSSY_STONE_BRICKS, Blocks.CRACKED_STONE_BRICKS, Blocks.CHISELED_STONE_BRICKS));
+ }
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_0_0tor1_0_1)) {
+ recipes.add(RecipeInfo.shapeless(Items.MUSHROOM_STEW, Blocks.BROWN_MUSHROOM, Blocks.RED_MUSHROOM, Items.BOWL));
+ recipes.add(RecipeInfo.shaped(4, Blocks.NETHER_BRICK_STAIRS, "# ", "## ", "###", '#', Blocks.NETHER_BRICKS));
+ recipes.add(RecipeInfo.shaped(6, Blocks.NETHER_BRICK_FENCE, "###", "###", '#', Blocks.NETHER_BRICKS));
+ recipes.add(RecipeInfo.shaped(3, Items.GLASS_BOTTLE, "# #", " # ", '#', Blocks.GLASS));
+ recipes.add(RecipeInfo.shaped(Blocks.BREWING_STAND, " B ", "###", 'B', Items.BLAZE_ROD, '#', Blocks.COBBLESTONE));
+ recipes.add(RecipeInfo.shaped(Blocks.CAULDRON, "# #", "# #", "###", '#', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shapeless(Items.ENDER_EYE, Items.ENDER_PEARL, Items.BLAZE_POWDER));
+ recipes.add(RecipeInfo.shaped(Blocks.ENCHANTING_TABLE, " B ", "D#D", "###", 'B', Items.BOOK, '#', Blocks.OBSIDIAN, 'D', Items.DIAMOND));
+ recipes.add(RecipeInfo.shaped(4, Blocks.PUMPKIN_STEM, "M", 'M', Blocks.CARVED_PUMPKIN));
+ recipes.add(RecipeInfo.shapeless(Items.FERMENTED_SPIDER_EYE, Items.SPIDER_EYE, Blocks.BROWN_MUSHROOM, Items.SUGAR));
+ recipes.add(RecipeInfo.shapeless(2, Items.BLAZE_POWDER, Items.BLAZE_ROD));
+ recipes.add(RecipeInfo.shapeless(Items.MAGMA_CREAM, Items.BLAZE_POWDER, Items.SLIME_BALL));
+ recipes.add(RecipeInfo.shaped(9, Items.GOLD_NUGGET, "#", '#', Items.GOLD_INGOT));
+ recipes.add(RecipeInfo.shaped("gold_ingot", Items.GOLD_INGOT, "###", "###", "###", '#', Items.GOLD_NUGGET));
+ } else {
+ recipes.add(RecipeInfo.shaped(Items.MUSHROOM_STEW, "Y", "X", "#", 'X', Blocks.BROWN_MUSHROOM, 'Y', Blocks.RED_MUSHROOM, '#', Items.BOWL));
+ recipes.add(RecipeInfo.shaped(Items.MUSHROOM_STEW, "Y", "X", "#", 'X', Blocks.RED_MUSHROOM, 'Y', Blocks.BROWN_MUSHROOM, '#', Items.BOWL));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_8tob1_8_1)) {
+ recipes.add(RecipeInfo.shaped(4, Blocks.BRICK_STAIRS, "# ", "## ", "###", '#', Blocks.BRICKS));
+ recipes.add(RecipeInfo.shaped(4, Blocks.STONE_BRICK_STAIRS, "# ", "## ", "###", '#', Blocks.STONE_BRICKS, Blocks.MOSSY_STONE_BRICKS, Blocks.CRACKED_STONE_BRICKS, Blocks.CHISELED_STONE_BRICKS));
+ recipes.add(RecipeInfo.shaped(4, Blocks.STONE_BRICKS, "##", "##", '#', Blocks.STONE));
+ recipes.add(RecipeInfo.shaped(16, Blocks.IRON_BARS, "###", "###", '#', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(16, Blocks.GLASS_PANE, "###", "###", '#', Blocks.GLASS));
+ recipes.add(RecipeInfo.shaped(Blocks.MELON, "MMM", "MMM", "MMM", 'M', Items.MELON_SLICE));
+ recipes.add(RecipeInfo.shaped(Blocks.MELON_STEM, "M", 'M', Items.MELON_SLICE));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_7tob1_7_3)) {
+ recipes.add(RecipeInfo.shaped(Blocks.STICKY_PISTON, "S", "P", 'P', Blocks.PISTON, 'S', Items.SLIME_BALL));
+ recipes.add(RecipeInfo.shaped(Blocks.PISTON, "TTT", "#X#", "#R#", 'R', Blocks.REDSTONE_WIRE, '#', Blocks.COBBLESTONE, 'T', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'X', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(Items.SHEARS, " #", "# ", '#', Items.IRON_INGOT));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_6tob1_6_6)) {
+ recipes.add(RecipeInfo.shaped(Blocks.GLOWSTONE, "##", "##", '#', Items.GLOWSTONE_DUST));
+ recipes.add(RecipeInfo.shaped(Blocks.WHITE_WOOL, "##", "##", '#', Blocks.TRIPWIRE));
+ recipes.add(RecipeInfo.shaped(2, Blocks.OAK_TRAPDOOR, "###", "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Items.MAP, "###", "#X#", "###", '#', Items.PAPER, 'X', Items.COMPASS));
+ } else {
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.a1_2_0toa1_2_1_1)) {
+ recipes.add(RecipeInfo.shaped(Blocks.GLOWSTONE, "###", "###", "###", '#', Items.GLOWSTONE_DUST));
+ }
+ recipes.add(RecipeInfo.shaped(Blocks.WHITE_WOOL, "###", "###", "###", '#', Blocks.TRIPWIRE));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_5tob1_5_2)) {
+ recipes.add(RecipeInfo.shaped(6, Blocks.DETECTOR_RAIL, "X X", "X#X", "XRX", 'R', Blocks.REDSTONE_WIRE, '#', Blocks.STONE_PRESSURE_PLATE, 'X', Items.IRON_INGOT));
+ recipes.add(RecipeInfo.shaped(6, Blocks.POWERED_RAIL, "X X", "X#X", "XRX", 'R', Blocks.REDSTONE_WIRE, '#', Items.STICK, 'X', Items.GOLD_INGOT));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_4tob1_4_1)) {
+ recipes.add(RecipeInfo.shaped(8, Items.COOKIE, "#X#", '#', Items.WHEAT, 'X', Blocks.COCOA));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_3tob1_3_1)) {
+ recipes.add(RecipeInfo.shaped(Blocks.REPEATER, "#X#", "III", '#', Blocks.REDSTONE_TORCH, 'X', Blocks.REDSTONE_WIRE, 'I', Blocks.STONE));
+ recipes.add(RecipeInfo.shaped(Blocks.OAK_PRESSURE_PLATE, "##", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Blocks.STONE_PRESSURE_PLATE, "##", '#', Blocks.STONE));
+ } else {
+ recipes.add(RecipeInfo.shaped(Blocks.OAK_PRESSURE_PLATE, "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
+ recipes.add(RecipeInfo.shaped(Blocks.STONE_PRESSURE_PLATE, "###", '#', Blocks.STONE));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_2_0tob1_2_2)) {
+ recipes.add(RecipeInfo.shaped(Blocks.NOTE_BLOCK, "###", "#X#", "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'X', Blocks.REDSTONE_WIRE));
+ recipes.add(RecipeInfo.shaped(Blocks.CAKE, "AAA", "BEB", "CCC", 'A', Items.MILK_BUCKET, 'B', Items.SUGAR, 'C', Items.WHEAT, 'E', Items.EGG));
+ recipes.add(RecipeInfo.shaped(Items.SUGAR, "#", '#', Blocks.SUGAR_CANE));
+ recipes.add(RecipeInfo.shaped(4, Blocks.TORCH, "X", "#", '#', Items.STICK, 'X', Items.COAL, Items.CHARCOAL));
+ recipes.add(RecipeInfo.shaped(Blocks.DISPENSER, "###", "#X#", "#R#", 'R', Blocks.REDSTONE_WIRE, '#', Blocks.COBBLESTONE, 'X', Items.BOW));
+ recipes.add(RecipeInfo.shaped(Blocks.SANDSTONE, "##", "##", '#', Blocks.SAND));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.YELLOW_WOOL, Items.YELLOW_DYE, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless("yellow_dye", Items.YELLOW_DYE, Blocks.DANDELION));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.RED_WOOL, Items.RED_DYE, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless("red_dye", Items.RED_DYE, Blocks.POPPY));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.PURPLE_WOOL, Items.PURPLE_DYE, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless(2, Items.PURPLE_DYE, Items.LAPIS_LAZULI, Items.RED_DYE));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.PINK_WOOL, Items.PINK_DYE, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless("pink_dye", 2, Items.PINK_DYE, Items.RED_DYE, Items.BONE_MEAL));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.ORANGE_WOOL, Items.ORANGE_DYE, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless("orange_dye", 2, Items.ORANGE_DYE, Items.RED_DYE, Items.YELLOW_DYE));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.MAGENTA_WOOL, Items.MAGENTA_DYE, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless("magenta_dye", 2, Items.MAGENTA_DYE, Items.PURPLE_DYE, Items.PINK_DYE));
+ recipes.add(RecipeInfo.shapeless("magenta_dye", 3, Items.MAGENTA_DYE, Items.LAPIS_LAZULI, Items.RED_DYE, Items.PINK_DYE));
+ recipes.add(RecipeInfo.shapeless("magenta_dye", 4, Items.MAGENTA_DYE, Items.LAPIS_LAZULI, Items.RED_DYE, Items.RED_DYE, Items.BONE_MEAL));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.LIME_WOOL, Items.LIME_DYE, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless(2, Items.LIME_DYE, Items.GREEN_DYE, Items.BONE_MEAL));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.LIGHT_GRAY_WOOL, Items.LIGHT_GRAY_DYE, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless("light_gray_dye", 3, Items.LIGHT_GRAY_DYE, Items.INK_SAC, Items.BONE_MEAL, Items.BONE_MEAL));
+ recipes.add(RecipeInfo.shapeless("light_gray_dye", 2, Items.LIGHT_GRAY_DYE, Items.GRAY_DYE, Items.BONE_MEAL));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.LIGHT_BLUE_WOOL, Items.LIGHT_BLUE_DYE, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless("light_blue_dye", 2, Items.LIGHT_BLUE_DYE, Items.LAPIS_LAZULI, Items.BONE_MEAL));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.GREEN_WOOL, Items.GREEN_DYE, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.GRAY_WOOL, Items.GRAY_DYE, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless(2, Items.GRAY_DYE, Items.INK_SAC, Items.BONE_MEAL));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.CYAN_WOOL, Items.CYAN_DYE, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless(2, Items.CYAN_DYE, Items.LAPIS_LAZULI, Items.GREEN_DYE));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.BLUE_WOOL, Items.LAPIS_LAZULI, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.BLACK_WOOL, Items.INK_SAC, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless("wool", Blocks.BROWN_WOOL, Blocks.COCOA, Blocks.WHITE_WOOL));
+ recipes.add(RecipeInfo.shapeless("bonemeal", 3, Items.BONE_MEAL, Items.BONE));
+ recipes.add(RecipeInfo.shaped(9, Items.LAPIS_LAZULI, "#", '#', Blocks.LAPIS_BLOCK));
+ recipes.add(RecipeInfo.shaped(Blocks.LAPIS_BLOCK, "###", "###", "###", '#', Items.LAPIS_LAZULI));
+ } else {
+ recipes.add(RecipeInfo.shaped(4, Blocks.TORCH, "X", "#", '#', Items.STICK, 'X', Items.COAL));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.a1_2_0toa1_2_1_1)) {
+ recipes.add(RecipeInfo.shaped(Blocks.JACK_O_LANTERN, "A", "B", 'A', Blocks.CARVED_PUMPKIN, 'B', Blocks.TORCH));
+ recipes.add(RecipeInfo.shaped(Items.CLOCK, " # ", "#X#", " # ", '#', Items.GOLD_INGOT, 'X', Blocks.REDSTONE_WIRE));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.a1_1_0toa1_1_2_1)) {
+ recipes.add(RecipeInfo.shaped(Items.FISHING_ROD, " #", " #X", "# X", '#', Items.STICK, 'X', Blocks.TRIPWIRE));
+ recipes.add(RecipeInfo.shaped(Items.COMPASS, " # ", "#X#", " # ", '#', Items.IRON_INGOT, 'X', Blocks.REDSTONE_WIRE));
+ }
+
+ recipes.add(RecipeInfo.smelting(Items.IRON_INGOT, Items.IRON_ORE, 0.7F));
+ recipes.add(RecipeInfo.smelting(Items.GOLD_INGOT, Items.GOLD_ORE, 1.0F));
+ recipes.add(RecipeInfo.smelting(Items.DIAMOND, Items.DIAMOND_ORE, 1.0F));
+ recipes.add(RecipeInfo.smelting(Items.GLASS, Ingredient.fromTag(ItemTags.SAND), 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.COOKED_PORKCHOP, Items.PORKCHOP, 0.35F));
+ recipes.add(RecipeInfo.smelting(Items.STONE, Items.COBBLESTONE, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.BRICK, Items.CLAY_BALL, 0.3F));
+
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_12)) {
+ recipes.add(RecipeInfo.smelting(Items.WHITE_GLAZED_TERRACOTTA, Items.WHITE_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.ORANGE_GLAZED_TERRACOTTA, Items.ORANGE_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.MAGENTA_GLAZED_TERRACOTTA, Items.MAGENTA_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.LIGHT_BLUE_GLAZED_TERRACOTTA, Items.LIGHT_BLUE_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.YELLOW_GLAZED_TERRACOTTA, Items.YELLOW_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.LIME_GLAZED_TERRACOTTA, Items.LIME_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.PINK_GLAZED_TERRACOTTA, Items.PINK_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.GRAY_GLAZED_TERRACOTTA, Items.GRAY_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.LIGHT_GRAY_GLAZED_TERRACOTTA, Items.LIGHT_GRAY_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.CYAN_GLAZED_TERRACOTTA, Items.CYAN_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.PURPLE_GLAZED_TERRACOTTA, Items.PURPLE_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.BLUE_GLAZED_TERRACOTTA, Items.BLUE_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.BROWN_GLAZED_TERRACOTTA, Items.BROWN_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.GREEN_GLAZED_TERRACOTTA, Items.GREEN_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.RED_GLAZED_TERRACOTTA, Items.RED_TERRACOTTA, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.BLACK_GLAZED_TERRACOTTA, Items.BLACK_TERRACOTTA, 0.1F));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_11_1to1_11_2)) {
+ recipes.add(RecipeInfo.smelting(Items.IRON_NUGGET, Ingredient.ofItems(Items.CHAINMAIL_HELMET, Items.CHAINMAIL_CHESTPLATE, Items.CHAINMAIL_LEGGINGS, Items.CHAINMAIL_BOOTS, Items.IRON_PICKAXE, Items.IRON_SHOVEL, Items.IRON_AXE, Items.IRON_HOE, Items.IRON_SWORD, Items.IRON_HELMET, Items.IRON_CHESTPLATE, Items.IRON_LEGGINGS, Items.IRON_BOOTS, Items.IRON_HORSE_ARMOR), 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.GOLD_NUGGET, Ingredient.ofItems(Items.GOLDEN_PICKAXE, Items.GOLDEN_SHOVEL, Items.GOLDEN_AXE, Items.GOLDEN_HOE, Items.GOLDEN_SWORD, Items.GOLDEN_HELMET, Items.GOLDEN_CHESTPLATE, Items.GOLDEN_LEGGINGS, Items.GOLDEN_BOOTS, Items.GOLDEN_HORSE_ARMOR), 0.1F));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_9)) {
+ recipes.add(RecipeInfo.smelting(Items.POPPED_CHORUS_FRUIT, Items.CHORUS_FRUIT, 0.1F));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_7_2tor1_7_5)) {
+ recipes.add(RecipeInfo.smelting(Items.COOKED_RABBIT, Items.RABBIT, 0.35F));
+ recipes.add(RecipeInfo.smelting(Items.COOKED_MUTTON, Items.MUTTON, 0.35F));
+ recipes.add(RecipeInfo.smelting(Items.CRACKED_STONE_BRICKS, Items.STONE_BRICKS, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.SPONGE, Items.WET_SPONGE, 0.15F));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_6_1)) {
+ recipes.add(RecipeInfo.smelting(Items.TERRACOTTA, Items.CLAY, 0.35F));
+ recipes.add(RecipeInfo.smelting(Items.COOKED_SALMON, Items.SALMON, 0.35F));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_5tor1_5_1)) {
+ recipes.add(RecipeInfo.smelting(Items.NETHER_BRICK, Items.NETHERRACK, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.QUARTZ, Items.NETHER_QUARTZ_ORE, 0.2F));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_4_2)) {
+ recipes.add(RecipeInfo.smelting(Items.BAKED_POTATO, Items.POTATO, 0.35F));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_3_1tor1_3_2)) {
+ recipes.add(RecipeInfo.smelting(Items.EMERALD, Items.EMERALD_ORE, 1.0F));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_0_0tor1_0_1)) {
+ recipes.add(RecipeInfo.smelting(Items.COAL, Items.COAL_ORE, 0.1F));
+ recipes.add(RecipeInfo.smelting(Items.REDSTONE, Items.REDSTONE_ORE, 0.7F));
+ recipes.add(RecipeInfo.smelting(Items.LAPIS_LAZULI, Items.LAPIS_ORE, 0.2F));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_8tob1_8_1)) {
+ recipes.add(RecipeInfo.smelting(Items.COOKED_CHICKEN, Items.CHICKEN, 0.35F));
+ recipes.add(RecipeInfo.smelting(Items.COOKED_BEEF, Items.BEEF, 0.35F));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.b1_2_0tob1_2_2)) {
+ recipes.add(RecipeInfo.smelting(Items.CHARCOAL, Ingredient.fromTag(ItemTags.LOGS), 0.15F));
+ recipes.add(RecipeInfo.smelting(Items.GREEN_DYE, Items.CACTUS, 0.2F));
+ }
+ if (ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.a1_2_0toa1_2_1_1)) {
+ recipes.add(RecipeInfo.smelting(Items.COOKED_COD, Items.COD, 0.35F));
+ }
+
+ return recipes;
+ }
+
+ /**
+ * Sets the result slot of a crafting screen handler to the correct item stack. In MC <= 1.11.2 the result slot
+ * is not updated when the input slots change, so we need to update it manually, Spigot and Paper re-syncs the slot,
+ * so we don't notice this bug on servers that use Spigot or Paper
+ *
+ * @param syncId The sync id of the screen handler
+ * @param screenHandler The screen handler
+ * @param inventory The inventory of the screen handler
+ */
+ public static void setCraftingResultSlot(final int syncId, final ScreenHandler screenHandler, final RecipeInputInventory inventory) {
+ final var network = MinecraftClient.getInstance().getNetworkHandler();
+ final var world = MinecraftClient.getInstance().world;
+
+ final var result = network.getRecipeManager()
+ .getFirstMatch(RecipeType.CRAFTING, inventory, world) // Get the first matching recipe
+ .map(recipe -> recipe.value().craft(inventory, network.getRegistryManager())) // Craft the recipe to get the result
+ .orElse(ItemStack.EMPTY); // If there is no recipe, set the result to air
+
+ // Update the result slot
+ network.onScreenHandlerSlotUpdate(new ScreenHandlerSlotUpdateS2CPacket(syncId, screenHandler.getRevision(), 0, result));
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/access/IChunkTracker.java b/src/main/java/de/florianmichael/viafabricplus/injection/access/IChunkTracker.java
new file mode 100644
index 000000000..b25600dfb
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/access/IChunkTracker.java
@@ -0,0 +1,30 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.access;
+
+public interface IChunkTracker {
+
+ int viaFabricPlus$getSubChunkRequests();
+
+ int viaFabricPlus$getPendingSubChunks();
+
+ int viaFabricPlus$getChunks();
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/access/IItemStack.java b/src/main/java/de/florianmichael/viafabricplus/injection/access/IItemStack.java
index d1d4a5e22..840bb0daf 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/access/IItemStack.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/access/IItemStack.java
@@ -21,7 +21,7 @@
public interface IItemStack {
- boolean viaFabricPlus$has1_10ProtocolHackTag();
+ boolean viaFabricPlus$has1_10ViaFabricPlusTag();
int viaFabricPlus$get1_10Count();
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/access/IMouseKeyboard.java b/src/main/java/de/florianmichael/viafabricplus/injection/access/IMouseKeyboard.java
new file mode 100644
index 000000000..73af73370
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/access/IMouseKeyboard.java
@@ -0,0 +1,28 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.access;
+
+import java.util.Queue;
+
+public interface IMouseKeyboard {
+
+ Queue viaFabricPlus$getPendingScreenEvents();
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/access/IRakSessionCodec.java b/src/main/java/de/florianmichael/viafabricplus/injection/access/IRakSessionCodec.java
new file mode 100644
index 000000000..013ceab06
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/access/IRakSessionCodec.java
@@ -0,0 +1,28 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.access;
+
+public interface IRakSessionCodec {
+
+ int viaFabricPlus$getOutgoingPackets();
+
+ int viaFabricPlus$SentDatagrams();
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/access/IScreenHandler.java b/src/main/java/de/florianmichael/viafabricplus/injection/access/IScreenHandler.java
index dc59f8216..1f8e8ed5c 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/access/IScreenHandler.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/access/IScreenHandler.java
@@ -21,5 +21,8 @@
public interface IScreenHandler {
- short viaFabricPlus$getAndIncrementLastActionId();
+ short viaFabricPlus$getActionId();
+
+ short viaFabricPlus$incrementAndGetActionId();
+
}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinChunkTracker.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinChunkTracker.java
new file mode 100644
index 000000000..96e146580
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinChunkTracker.java
@@ -0,0 +1,62 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.mixin.base.integration;
+
+import de.florianmichael.viafabricplus.injection.access.IChunkTracker;
+import net.raphimc.viabedrock.api.chunk.BedrockChunk;
+import net.raphimc.viabedrock.protocol.storage.ChunkTracker;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+
+import java.util.Map;
+import java.util.Set;
+
+@Mixin(value = ChunkTracker.class, remap = false)
+public abstract class MixinChunkTracker implements IChunkTracker {
+
+ @Shadow
+ @Final
+ private Set> subChunkRequests;
+
+ @Shadow
+ @Final
+ private Set> pendingSubChunks;
+
+ @Shadow
+ @Final
+ private Map chunks;
+
+ @Override
+ public int viaFabricPlus$getSubChunkRequests() {
+ return this.subChunkRequests.size();
+ }
+
+ @Override
+ public int viaFabricPlus$getPendingSubChunks() {
+ return this.pendingSubChunks.size();
+ }
+
+ @Override
+ public int viaFabricPlus$getChunks() {
+ return this.chunks.size();
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinConnectScreen_1.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinConnectScreen_1.java
index 44a1fd494..62dc0687e 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinConnectScreen_1.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinConnectScreen_1.java
@@ -19,30 +19,71 @@
package de.florianmichael.viafabricplus.injection.mixin.base.integration;
+import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.ViaFabricPlus;
-import de.florianmichael.viafabricplus.protocolhack.provider.vialegacy.ViaFabricPlusClassicMPPassProvider;
-import de.florianmichael.viafabricplus.settings.impl.AuthenticationSettings;
-import net.minecraft.client.MinecraftClient;
-import net.minecraft.network.ClientConnection;
-import net.minecraft.network.packet.Packet;
-import net.minecraft.network.packet.c2s.login.LoginHelloC2SPacket;
+import de.florianmichael.viafabricplus.injection.access.IServerInfo;
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import de.florianmichael.viafabricplus.settings.impl.GeneralSettings;
+import net.lenni0451.mcping.MCPing;
+import net.minecraft.client.gui.screen.ConnectScreen;
+import net.minecraft.client.network.ServerInfo;
+import net.minecraft.client.session.Session;
+import net.minecraft.text.Text;
+import net.raphimc.vialoader.util.VersionEnum;
+import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
+
+import java.net.InetSocketAddress;
@Mixin(targets = "net.minecraft.client.gui.screen.ConnectScreen$1")
public abstract class MixinConnectScreen_1 {
- @Redirect(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;send(Lnet/minecraft/network/packet/Packet;)V"))
- private void spoofUserName(ClientConnection instance, Packet> packet) {
- if (AuthenticationSettings.global().setSessionNameToClassiCubeNameInServerList.getValue() && ViaFabricPlusClassicMPPassProvider.classiCubeMPPass != null) {
- final var account = ViaFabricPlus.global().getSaveManager().getAccountsSave().getClassicubeAccount();
- if (account != null) {
- instance.send(new LoginHelloC2SPacket(account.username(), MinecraftClient.getInstance().getSession().getUuidOrNull()));
- return;
- }
+ @Shadow
+ @Final
+ ServerInfo field_40415;
+
+ @Shadow
+ @Final
+ ConnectScreen field_2416;
+
+ @Redirect(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/session/Session;getUsername()Ljava/lang/String;"))
+ private String useClassiCubeUsername(Session instance) {
+ final var account = ViaFabricPlus.global().getSaveManager().getAccountsSave().getClassicubeAccount();
+ if (account != null) {
+ return account.username();
}
- instance.send(packet);
+ return instance.getUsername();
}
-}
\ No newline at end of file
+
+ @SuppressWarnings("InvalidInjectorMethodSignature")
+ @Inject(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/network/ClientConnection;)Lio/netty/channel/ChannelFuture;", shift = At.Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILHARD)
+ private void setServerInfo(CallbackInfo ci, InetSocketAddress inetSocketAddress) {
+ final VersionEnum serverVersion = ((IServerInfo) this.field_40415).viaFabricPlus$forcedVersion();
+ if (serverVersion != null) {
+ ProtocolHack.setTargetVersion(serverVersion);
+ } else if (GeneralSettings.global().autoDetectVersion.getValue()) {
+ this.field_2416.setStatus(Text.translatable("base.viafabricplus.detecting_server_version"));
+ MCPing
+ .pingModern(-1)
+ .address(inetSocketAddress.getHostString(), inetSocketAddress.getPort())
+ .noResolve()
+ .timeout(1000, 1000)
+ .exceptionHandler(t -> {
+ })
+ .responseHandler(r -> {
+ if (ProtocolVersion.isRegistered(r.version.protocol)) {
+ ProtocolHack.setTargetVersion(VersionEnum.fromProtocolId(r.version.protocol));
+ }
+ })
+ .getSync();
+ }
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinDebugHud.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinDebugHud.java
index 400bd170b..4ac62ab8e 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinDebugHud.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinDebugHud.java
@@ -26,21 +26,26 @@
import de.florianmichael.viafabricplus.fixes.tracker.JoinGameTracker;
import de.florianmichael.viafabricplus.injection.ViaFabricPlusMixinPlugin;
import de.florianmichael.viafabricplus.injection.access.IBlobCache;
+import de.florianmichael.viafabricplus.injection.access.IChunkTracker;
+import de.florianmichael.viafabricplus.injection.access.IRakSessionCodec;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import de.florianmichael.viafabricplus.protocolhack.provider.viabedrock.ViaFabricPlusBlobCacheProvider;
import de.florianmichael.viafabricplus.settings.impl.GeneralSettings;
import de.florianmichael.viafabricplus.util.ChatUtil;
import de.florianmichael.viafabricplus.util.StringUtil;
-import net.lenni0451.reflect.stream.RStream;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.hud.DebugHud;
+import net.minecraft.util.Formatting;
import net.raphimc.viabedrock.protocol.data.enums.bedrock.ServerMovementModes;
import net.raphimc.viabedrock.protocol.providers.BlobCacheProvider;
import net.raphimc.viabedrock.protocol.storage.BlobCache;
+import net.raphimc.viabedrock.protocol.storage.ChunkTracker;
import net.raphimc.viabedrock.protocol.storage.GameSessionStorage;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.storage.ExtensionProtocolMetadataStorage;
import net.raphimc.vialegacy.protocols.release.protocol1_2_1_3to1_1.storage.SeedStorage;
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.storage.EntityTracker;
+import org.cloudburstmc.netty.channel.raknet.RakClientChannel;
+import org.cloudburstmc.netty.handler.codec.raknet.common.RakSessionCodec;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -48,8 +53,6 @@
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
@SuppressWarnings("DataFlowIssue")
@Mixin(DebugHud.class)
@@ -69,19 +72,39 @@ public void addViaFabricPlusInformation(CallbackInfoReturnable
> cir
information.add("");
// Title
- information.add(ChatUtil.PREFIX + " " + ViaFabricPlusMixinPlugin.VFP_VERSION);
+ information.add(ChatUtil.PREFIX + Formatting.GRAY + " " + ViaFabricPlusMixinPlugin.VFP_VERSION);
// common
final ProtocolInfo info = userConnection.getProtocolInfo();
information.add(
- "P: " + info.getPipeline().pipes().size() +
- " / C: " + ProtocolVersion.getProtocol(info.getProtocolVersion()) +
- " / S: " + ProtocolVersion.getProtocol(info.getServerProtocolVersion())
+ "P: " + info.getPipeline().pipes().size() +
+ " C: " + ProtocolVersion.getProtocol(info.getProtocolVersion()) +
+ " S: " + ProtocolVersion.getProtocol(info.getServerProtocolVersion())
);
+ // r1_7_10
+ final EntityTracker entityTracker1_7_10 = userConnection.get(EntityTracker.class);
+ if (entityTracker1_7_10 != null) {
+ information.add(
+ "1.7 Entities: " + entityTracker1_7_10.getTrackedEntities().size() +
+ ", Virtual holograms: " + entityTracker1_7_10.getVirtualHolograms().size()
+ );
+ }
+
+ // r1_1
+ final SeedStorage seedStorage = userConnection.get(SeedStorage.class);
+ if (seedStorage != null) {
+ information.add("World Seed: " + seedStorage.seed);
+ }
+
+ // c0.30cpe
+ final ExtensionProtocolMetadataStorage extensionProtocolMetadataStorage = userConnection.get(ExtensionProtocolMetadataStorage.class);
+ if (extensionProtocolMetadataStorage != null) {
+ information.add("CPE extensions: " + extensionProtocolMetadataStorage.getExtensionCount());
+ }
+
// bedrock
final JoinGameTracker joinGameTracker = userConnection.get(JoinGameTracker.class);
-
if (joinGameTracker != null) {
final int movementMode = userConnection.get(GameSessionStorage.class).getMovementMode();
String movement = "Server with rewind";
@@ -91,7 +114,10 @@ public void addViaFabricPlusInformation(CallbackInfoReturnable> cir
movement = "Server";
}
- information.add("Bedrock Level: " + joinGameTracker.getLevelId() + " / Enchantment Seed: " + joinGameTracker.getEnchantmentSeed() + " / Movement: " + movement);
+ information.add("Bedrock Level: " + joinGameTracker.getLevelId() + ", Enchantment Seed: " + joinGameTracker.getEnchantmentSeed() + ", Movement: " + movement);
+ }
+ if (joinGameTracker != null) {
+ information.add("World Seed: " + joinGameTracker.getSeed());
}
final BlobCache blobCache = userConnection.get(BlobCache.class);
if (blobCache != null) {
@@ -101,32 +127,22 @@ public void addViaFabricPlusInformation(CallbackInfoReturnable> cir
final int blobCount = blobCacheProvider.getBlobs().size();
final int pendingCount = ((IBlobCache) blobCache).viaFabricPlus$getPending().size();
- if (totalSize != 0 || blobCount != 0 || pendingCount != 0) {
- information.add("Blob Cache: S: " + StringUtil.formatBytes(totalSize) + " / C: " + blobCount + " / Pending: " + pendingCount);
- }
- }
-
- // r1_7_10
- final EntityTracker entityTracker1_7_10 = userConnection.get(EntityTracker.class);
- if (entityTracker1_7_10 != null) {
- information.add(
- "1.7 Entities: " + entityTracker1_7_10.getTrackedEntities().size() +
- " / Virtual holograms: " + entityTracker1_7_10.getVirtualHolograms().size()
- );
+ information.add("Blob Cache: S: " + StringUtil.formatBytes(totalSize) + ", C: " + blobCount + ", P: " + pendingCount);
}
-
- // r1_1 and bedrock
- final SeedStorage seedStorage = userConnection.get(SeedStorage.class);
- if (seedStorage != null) {
- information.add("World Seed: " + seedStorage.seed);
- } else if (joinGameTracker != null) {
- information.add("World Seed: " + joinGameTracker.getSeed());
+ final ChunkTracker chunkTracker = userConnection.get(ChunkTracker.class);
+ if (chunkTracker != null) {
+ final int subChunkRequests = ((IChunkTracker) chunkTracker).viaFabricPlus$getSubChunkRequests();
+ final int pendingSubChunks = ((IChunkTracker) chunkTracker).viaFabricPlus$getPendingSubChunks();
+ final int chunks = ((IChunkTracker) chunkTracker).viaFabricPlus$getChunks();
+ cir.getReturnValue().add("Chunk Tracker: R: " + subChunkRequests + ", P: " + pendingSubChunks + ", C: " + chunks);
}
-
- // c0.30cpe
- final ExtensionProtocolMetadataStorage extensionProtocolMetadataStorage = userConnection.get(ExtensionProtocolMetadataStorage.class);
- if (extensionProtocolMetadataStorage != null) {
- information.add("CPE extensions: " + extensionProtocolMetadataStorage.getExtensionCount());
+ if (userConnection.getChannel() instanceof RakClientChannel rakClientChannel) {
+ final RakSessionCodec rakSessionCodec = rakClientChannel.parent().pipeline().get(RakSessionCodec.class);
+ if (rakSessionCodec != null) {
+ final int transmitQueue = ((IRakSessionCodec) rakSessionCodec).viaFabricPlus$getOutgoingPackets();
+ final int retransmitQueue = ((IRakSessionCodec) rakSessionCodec).viaFabricPlus$SentDatagrams();
+ cir.getReturnValue().add("RTT: " + Math.round(rakSessionCodec.getRTT()) + " ms, P: " + rakSessionCodec.getPing() + " ms" + ", TQ: " + transmitQueue + ", RTQ: " + retransmitQueue);
+ }
}
information.add("");
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinDownloadingTerrainScreen.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinDownloadingTerrainScreen.java
index 226d8908b..1e6fb79f2 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinDownloadingTerrainScreen.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinDownloadingTerrainScreen.java
@@ -45,6 +45,9 @@ private void renderClassicProgress(DrawContext context, int mouseX, int mouseY,
if (GeneralSettings.global().showClassicLoadingProgressInConnectScreen.getValue()) {
// Check if ViaVersion is translating
final UserConnection connection = ProtocolHack.getPlayNetworkUserConnection();
+ if (connection == null) {
+ return;
+ }
// Check if the client is connecting to a classic server
final ClassicProgressStorage classicProgressStorage = connection.get(ClassicProgressStorage.class);
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinMultiplayerServerListWidget_ServerEntry.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinMultiplayerServerListWidget_ServerEntry.java
index 4a55a7b8e..4d8cf3417 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinMultiplayerServerListWidget_ServerEntry.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinMultiplayerServerListWidget_ServerEntry.java
@@ -21,20 +21,15 @@
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
-import de.florianmichael.viafabricplus.injection.access.IServerInfo;
-import de.florianmichael.viafabricplus.settings.impl.GeneralSettings;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.text.Text;
-import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Redirect;
-import java.util.ArrayList;
import java.util.List;
@Mixin(MultiplayerServerListWidget.ServerEntry.class)
@@ -46,7 +41,7 @@ public abstract class MixinMultiplayerServerListWidget_ServerEntry {
@WrapOperation(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;setMultiplayerScreenTooltip(Ljava/util/List;)V", ordinal = 0))
private void drawTranslatingState(MultiplayerScreen instance, List tooltip, Operation original) {
- if (GeneralSettings.global().showAdvertisedServerVersion.getValue()) {
+ /*if (GeneralSettings.global().showAdvertisedServerVersion.getValue()) {
final IServerInfo mixinServerInfo = ((IServerInfo) server);
if (mixinServerInfo.viaFabricPlus$enabled()) {
@@ -55,7 +50,7 @@ private void drawTranslatingState(MultiplayerScreen instance, List tooltip
tooltip.add(Text.translatable("base.viafabricplus.via_translates_to", versionEnum != VersionEnum.UNKNOWN ? versionEnum.getName() + " (" + versionEnum.getVersion() + ")" : mixinServerInfo.viaFabricPlus$translatingVersion()));
tooltip.add(Text.translatable("base.viafabricplus.server_version", server.version.getString() + " (" + server.protocolVersion + ")"));
}
- }
+ }*/
original.call(instance, tooltip);
}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinRakSessionCodec.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinRakSessionCodec.java
new file mode 100644
index 000000000..45b180fe2
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/base/integration/MixinRakSessionCodec.java
@@ -0,0 +1,50 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.mixin.base.integration;
+
+import de.florianmichael.viafabricplus.injection.access.IRakSessionCodec;
+import io.netty.util.collection.IntObjectMap;
+import org.cloudburstmc.netty.channel.raknet.packet.EncapsulatedPacket;
+import org.cloudburstmc.netty.channel.raknet.packet.RakDatagramPacket;
+import org.cloudburstmc.netty.handler.codec.raknet.common.RakSessionCodec;
+import org.cloudburstmc.netty.util.FastBinaryMinHeap;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+
+@Mixin(value = RakSessionCodec.class, remap = false)
+public abstract class MixinRakSessionCodec implements IRakSessionCodec {
+
+ @Shadow
+ private FastBinaryMinHeap outgoingPackets;
+
+ @Shadow
+ private IntObjectMap sentDatagrams;
+
+ @Override
+ public int viaFabricPlus$getOutgoingPackets() {
+ return this.outgoingPackets.size();
+ }
+
+ @Override
+ public int viaFabricPlus$SentDatagrams() {
+ return this.sentDatagrams.size();
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/authlib/MixinKeyPairResponse.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/authlib/MixinKeyPairResponse.java
index ed8714399..4bbedd86a 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/authlib/MixinKeyPairResponse.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/authlib/MixinKeyPairResponse.java
@@ -39,4 +39,5 @@ public abstract class MixinKeyPairResponse implements ILegacyKeySignatureStorage
public void viafabricplus$setLegacyPublicKeySignature(byte[] signature) {
this.viaFabricPlus$legacyKeySignature = signature;
}
+
}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/authlib/MixinYggdrasilUserApiService.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/authlib/MixinYggdrasilUserApiService.java
index 247bdce90..321f01258 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/authlib/MixinYggdrasilUserApiService.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/authlib/MixinYggdrasilUserApiService.java
@@ -22,8 +22,9 @@
import com.mojang.authlib.minecraft.client.MinecraftClient;
import com.mojang.authlib.yggdrasil.YggdrasilUserApiService;
import com.mojang.authlib.yggdrasil.response.KeyPairResponse;
-import de.florianmichael.viafabricplus.injection.reference.KeyPairResponse1_19_0;
+import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.injection.access.ILegacyKeySignatureStorage;
+import de.florianmichael.viafabricplus.injection.reference.KeyPairResponse1_19_0;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -36,9 +37,13 @@
@Mixin(value = YggdrasilUserApiService.class, remap = false)
public abstract class MixinYggdrasilUserApiService {
- @Shadow @Final private MinecraftClient minecraftClient;
+ @Shadow
+ @Final
+ private MinecraftClient minecraftClient;
- @Shadow @Final private URL routeKeyPair;
+ @Shadow
+ @Final
+ private URL routeKeyPair;
@Inject(method = "getKeyPair", at = @At("HEAD"), cancellable = true)
private void storeLegacyPublicKeySignature(CallbackInfoReturnable cir) {
@@ -58,8 +63,11 @@ private void storeLegacyPublicKeySignature(CallbackInfoReturnable.
*/
-package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.screen;
+package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
-import de.florianmichael.viafabricplus.fixes.TripleChestHandler1_13_2;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
-import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
-import net.minecraft.client.gui.screen.ingame.HandledScreens;
-import net.minecraft.screen.GenericContainerScreenHandler;
-import net.minecraft.screen.ScreenHandler;
-import net.minecraft.screen.ScreenHandlerType;
+import net.minecraft.client.network.Address;
+import net.minecraft.client.network.AddressResolver;
+import net.minecraft.client.network.AllowedAddressResolver;
+import net.minecraft.client.network.ServerAddress;
import net.raphimc.vialoader.util.VersionEnum;
-import org.jetbrains.annotations.Nullable;
+import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-@Mixin(HandledScreens.class)
-public abstract class MixinHandledScreens {
+import java.util.Optional;
- @Inject(method = "getProvider", at = @At("HEAD"), cancellable = true)
- private static void returnFakeProvider(ScreenHandlerType type, CallbackInfoReturnable cir) {
- if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2) && type instanceof TripleChestHandler1_13_2.TripleChestScreenHandlerType) {
- cir.setReturnValue((handler, playerInventory, title) -> new GenericContainerScreen((GenericContainerScreenHandler) handler, playerInventory, title));
+@Mixin(AllowedAddressResolver.class)
+public abstract class MixinAllowedAddressResolver {
+
+ @Shadow
+ @Final
+ private AddressResolver addressResolver;
+
+ @Inject(method = "resolve", at = @At("HEAD"), cancellable = true)
+ private void oldResolveBehaviour(ServerAddress address, CallbackInfoReturnable> cir) {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_4tor1_16_5) || ProtocolHack.getTargetVersion().equals(VersionEnum.bedrockLatest)) {
+ cir.setReturnValue(this.addressResolver.resolve(address));
}
}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/screen/merchant/MixinMerchantScreenHandler.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinBuiltChunk.java
similarity index 75%
rename from src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/screen/merchant/MixinMerchantScreenHandler.java
rename to src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinBuiltChunk.java
index d3a7c9988..3e2ff1c57 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/screen/merchant/MixinMerchantScreenHandler.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinBuiltChunk.java
@@ -17,24 +17,23 @@
* along with this program. If not, see .
*/
-package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.screen.merchant;
+package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
-import net.raphimc.vialoader.util.VersionEnum;
-import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
-import net.minecraft.screen.MerchantScreenHandler;
+import net.minecraft.client.render.chunk.ChunkBuilder;
+import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-@Mixin(MerchantScreenHandler.class)
-public abstract class MixinMerchantScreenHandler {
+@Mixin(ChunkBuilder.BuiltChunk.class)
+public abstract class MixinBuiltChunk {
- @Inject(method = "switchTo", at = @At("HEAD"), cancellable = true)
- private void dontSwitchTo(int recipeId, CallbackInfo ci) {
- if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
- ci.cancel();
+ @Inject(method = "shouldBuild", at = @At("HEAD"), cancellable = true)
+ private void modifyRenderCondition(CallbackInfoReturnable cir) {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
+ cir.setReturnValue(true);
}
}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinChatInputSuggestor.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinChatInputSuggestor.java
new file mode 100644
index 000000000..177e565f2
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinChatInputSuggestor.java
@@ -0,0 +1,95 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
+
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.ChatInputSuggestor;
+import net.minecraft.client.gui.widget.TextFieldWidget;
+import net.minecraft.text.OrderedText;
+import net.minecraft.text.Style;
+import net.raphimc.vialoader.util.VersionEnum;
+import org.jetbrains.annotations.Nullable;
+import org.lwjgl.glfw.GLFW;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+import java.util.List;
+
+@Mixin(ChatInputSuggestor.class)
+public abstract class MixinChatInputSuggestor {
+
+ @Shadow
+ public abstract void refresh();
+
+ @Shadow
+ @Nullable
+ private ChatInputSuggestor.@Nullable SuggestionWindow window;
+
+ @Shadow
+ @Final
+ TextFieldWidget textField;
+
+ @Shadow
+ @Final
+ private List messages;
+
+ @Inject(method = "provideRenderText", at = @At(value = "HEAD"), cancellable = true)
+ private void disableTextFieldColors(String original, int firstCharacterIndex, CallbackInfoReturnable cir) {
+ if (!this.cancelTabComplete()) return;
+
+ cir.setReturnValue(OrderedText.styledForwardsVisitedString(original, Style.EMPTY));
+ }
+
+ @Inject(method = "keyPressed", at = @At("HEAD"), cancellable = true)
+ private void handle1_12_2KeyPressed(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable cir) {
+ if (!this.cancelTabComplete()) return;
+
+ if (keyCode == GLFW.GLFW_KEY_TAB && this.window == null) {
+ this.refresh();
+ } else if (this.window != null) {
+ if (this.window.keyPressed(keyCode, scanCode, modifiers)) {
+ cir.setReturnValue(true);
+ return;
+ }
+ this.textField.setSuggestion(null);
+ this.window = null;
+ }
+ }
+
+ @Inject(method = "render", at = @At("HEAD"))
+ private void clearMessages(DrawContext drawContext, int mouseX, int mouseY, CallbackInfo ci) {
+ if (!this.cancelTabComplete()) return;
+
+ this.messages.clear();
+ }
+
+ @Unique
+ private boolean cancelTabComplete() {
+ return ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2) && this.textField.getText().startsWith("/");
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientCommandSource.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientCommandSource.java
new file mode 100644
index 000000000..26da11a2e
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientCommandSource.java
@@ -0,0 +1,49 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
+
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import net.minecraft.client.network.ClientCommandSource;
+import net.raphimc.vialoader.util.VersionEnum;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+import java.util.Collection;
+import java.util.Set;
+
+@Mixin(ClientCommandSource.class)
+public abstract class MixinClientCommandSource {
+
+ @Shadow
+ @Final
+ private Set chatSuggestions;
+
+ @Inject(method = {"getPlayerNames", "getChatSuggestions"}, at = @At("HEAD"), cancellable = true)
+ private void returnChatSuggestions(CallbackInfoReturnable> cir) {
+ if (ProtocolHack.getTargetVersion().equals(VersionEnum.bedrockLatest)) {
+ cir.setReturnValue(this.chatSuggestions);
+ }
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientPlayerInteractionManager.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientPlayerInteractionManager.java
deleted file mode 100644
index 4a715bbcc..000000000
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientPlayerInteractionManager.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
- * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
- * Copyright (C) 2023 RK_01/RaphiMC and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
-
-import com.llamalad7.mixinextras.injector.WrapWithCondition;
-import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
-import com.viaversion.viaversion.api.type.Type;
-import com.viaversion.viaversion.protocols.protocol1_16_2to1_16_1.ServerboundPackets1_16_2;
-import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.Protocol1_17To1_16_4;
-import de.florianmichael.viafabricplus.ViaFabricPlus;
-import de.florianmichael.viafabricplus.fixes.ClientPlayerInteractionManager1_18_2;
-import de.florianmichael.viafabricplus.injection.access.IClientConnection;
-import de.florianmichael.viafabricplus.injection.access.IScreenHandler;
-import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
-import de.florianmichael.viafabricplus.protocolhack.provider.viaversion.ViaFabricPlusHandItemProvider;
-import de.florianmichael.viafabricplus.protocolhack.util.ItemTranslator;
-import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.network.ClientPlayNetworkHandler;
-import net.minecraft.client.network.ClientPlayerEntity;
-import net.minecraft.client.network.ClientPlayerInteractionManager;
-import net.minecraft.client.network.SequencedPacketCreator;
-import net.minecraft.client.world.ClientWorld;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.item.ItemStack;
-import net.minecraft.network.packet.Packet;
-import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket;
-import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
-import net.minecraft.screen.slot.SlotActionType;
-import net.minecraft.util.ActionResult;
-import net.minecraft.util.Hand;
-import net.minecraft.util.hit.BlockHitResult;
-import net.minecraft.util.math.BlockPos;
-import net.raphimc.vialoader.util.VersionEnum;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.Unique;
-import org.spongepowered.asm.mixin.injection.*;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-import java.util.List;
-
-@SuppressWarnings("DataFlowIssue")
-@Mixin(ClientPlayerInteractionManager.class)
-public abstract class MixinClientPlayerInteractionManager {
-
- @Shadow
- @Final
- private MinecraftClient client;
-
- @Shadow
- protected abstract ActionResult interactBlockInternal(ClientPlayerEntity player, Hand hand, BlockHitResult hitResult);
-
- @Shadow
- @Final
- private ClientPlayNetworkHandler networkHandler;
-
- @Shadow
- private BlockPos currentBreakingPos;
-
- @Shadow private float currentBreakingProgress;
- @Unique
- private ItemStack viaFabricPlus$oldCursorStack;
-
- @Unique
- private List viaFabricPlus$oldItems;
-
- @Inject(method = "getBlockBreakingProgress", at = @At("HEAD"), cancellable = true)
- private void changeCalculation(CallbackInfoReturnable cir) {
- if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_4)) {
- cir.setReturnValue((int)(this.currentBreakingProgress * 10.0F) - 1);
- }
- }
-
- @Inject(method = "sendSequencedPacket", at = @At("HEAD"))
- private void handleBlockAcknowledgements(ClientWorld world, SequencedPacketCreator packetCreator, CallbackInfo ci) {
- if (ProtocolHack.getTargetVersion().isBetweenInclusive(VersionEnum.r1_14_4, VersionEnum.r1_18_2) && packetCreator instanceof PlayerActionC2SPacket playerActionC2SPacket) {
- ClientPlayerInteractionManager1_18_2.trackBlockAction(playerActionC2SPacket.getAction(), playerActionC2SPacket.getPos());
- }
- }
-
- @ModifyVariable(method = "clickSlot", at = @At(value = "STORE"), ordinal = 0)
- private List captureOldItems(List oldItems) {
- assert client.player != null;
- viaFabricPlus$oldCursorStack = client.player.currentScreenHandler.getCursorStack().copy();
- return this.viaFabricPlus$oldItems = oldItems;
- }
-
- // Special Cases
- @Unique
- private boolean viaFabricPlus$shouldEmpty(final SlotActionType type, final int slot) {
- // quick craft always uses empty stack for verification
- if (type == SlotActionType.QUICK_CRAFT) return true;
-
- // quick move always uses empty stack for verification since 1.12
- if (type == SlotActionType.QUICK_MOVE && ProtocolHack.getTargetVersion().isNewerThan(VersionEnum.r1_11_1to1_11_2)) return true;
-
- // pickup with slot -999 (outside window) to throw items always uses empty stack for verification
- return type == SlotActionType.PICKUP && slot == -999;
- }
-
- @WrapWithCondition(method = "clickSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;)V"))
- private boolean modifySlotClickPacket(ClientPlayNetworkHandler instance, Packet> packet) {
- if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_4tor1_16_5) && packet instanceof ClickSlotC2SPacket clickSlot) {
- ItemStack slotItemBeforeModification;
-
- if (this.viaFabricPlus$shouldEmpty(clickSlot.getActionType(), clickSlot.getSlot()))
- slotItemBeforeModification = ItemStack.EMPTY;
- else if (clickSlot.getSlot() < 0 || clickSlot.getSlot() >= viaFabricPlus$oldItems.size())
- slotItemBeforeModification = viaFabricPlus$oldCursorStack;
- else
- slotItemBeforeModification = viaFabricPlus$oldItems.get(clickSlot.getSlot());
-
- final var clickSlotPacket = PacketWrapper.create(ServerboundPackets1_16_2.CLICK_WINDOW, ((IClientConnection)networkHandler.getConnection()).viaFabricPlus$getUserConnection());
-
- clickSlotPacket.write(Type.UNSIGNED_BYTE, (short) clickSlot.getSyncId());
- clickSlotPacket.write(Type.SHORT, (short) clickSlot.getSlot());
- clickSlotPacket.write(Type.BYTE, (byte) clickSlot.getButton());
- clickSlotPacket.write(Type.SHORT, ((IScreenHandler) client.player.currentScreenHandler).viaFabricPlus$getAndIncrementLastActionId());
- clickSlotPacket.write(Type.VAR_INT, clickSlot.getActionType().ordinal());
- clickSlotPacket.write(Type.ITEM1_13_2, ItemTranslator.MC_TO_VIA_LATEST_TO_TARGET(slotItemBeforeModification, VersionEnum.r1_16));
-
- try {
- clickSlotPacket.sendToServer(Protocol1_17To1_16_4.class);
- } catch (Exception e) {
- ViaFabricPlus.global().getLogger().error("Failed to send Click Slot Packet", e);
- }
-
- viaFabricPlus$oldCursorStack = null;
- viaFabricPlus$oldItems = null;
- return false;
- }
- return true;
- }
-
- @WrapWithCondition(method = "interactItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;)V", ordinal = 0),
- slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;syncSelectedSlot()V"),
- to = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;sendSequencedPacket(Lnet/minecraft/client/world/ClientWorld;Lnet/minecraft/client/network/SequencedPacketCreator;)V", ordinal = 0)))
- private boolean redirectInteractItem(ClientPlayNetworkHandler instance, Packet> packet) {
- return ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_17);
- }
-
- @Inject(method = "breakBlock", at = @At("TAIL"))
- private void resetBlockBreaking(BlockPos pos, CallbackInfoReturnable cir) {
- if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_14_3)) {
- this.currentBreakingPos = new BlockPos(this.currentBreakingPos.getX(), -1, this.currentBreakingPos.getZ());
- }
- }
-
- @Unique
- private ActionResult viaFabricPlus$actionResult;
-
- @Inject(method = "interactBlock", at = @At("HEAD"), cancellable = true)
- private void cacheActionResult(ClientPlayerEntity player, Hand hand, BlockHitResult hitResult, CallbackInfoReturnable cir) {
- if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2)) {
- this.viaFabricPlus$actionResult = this.interactBlockInternal(player, hand, hitResult);
-
- if (this.viaFabricPlus$actionResult == ActionResult.FAIL) {
- cir.setReturnValue(this.viaFabricPlus$actionResult);
- }
- }
- }
-
- @Redirect(method = "method_41933", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;interactBlockInternal(Lnet/minecraft/client/network/ClientPlayerEntity;Lnet/minecraft/util/Hand;Lnet/minecraft/util/hit/BlockHitResult;)Lnet/minecraft/util/ActionResult;"))
- private ActionResult provideCachedResult(ClientPlayerInteractionManager instance, ClientPlayerEntity player, Hand hand, BlockHitResult hitResult) {
- if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2)) {
- return this.viaFabricPlus$actionResult;
- }
- return interactBlockInternal(player, hand, hitResult);
- }
-
- @Inject(method = "interactItem", at = @At("HEAD"))
- private void trackLastUsedItem(PlayerEntity player, Hand hand, CallbackInfoReturnable cir) {
- ViaFabricPlusHandItemProvider.lastUsedItem = player.getStackInHand(hand).copy();
- }
-
- @Inject(method = "interactBlock", at = @At("HEAD"))
- private void trackLastUsedBlock(ClientPlayerEntity player, Hand hand, BlockHitResult hitResult, CallbackInfoReturnable cir) {
- ViaFabricPlusHandItemProvider.lastUsedItem = player.getStackInHand(hand).copy();
- }
-
-}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientWorld.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientWorld.java
new file mode 100644
index 000000000..d2e2f5185
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinClientWorld.java
@@ -0,0 +1,135 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
+
+import de.florianmichael.viafabricplus.fixes.PendingUpdateManager1_18_2;
+import de.florianmichael.viafabricplus.injection.access.IEntity;
+import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
+import net.minecraft.client.network.ClientPlayNetworkHandler;
+import net.minecraft.client.network.PendingUpdateManager;
+import net.minecraft.client.render.WorldRenderer;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.registry.DynamicRegistryManager;
+import net.minecraft.registry.Registries;
+import net.minecraft.registry.RegistryKey;
+import net.minecraft.registry.entry.RegistryEntry;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.util.profiler.Profiler;
+import net.minecraft.world.EntityList;
+import net.minecraft.world.MutableWorldProperties;
+import net.minecraft.world.World;
+import net.minecraft.world.dimension.DimensionType;
+import org.spongepowered.asm.mixin.*;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import java.util.function.Supplier;
+
+@Mixin(value = ClientWorld.class, priority = 900)
+public abstract class MixinClientWorld extends World {
+
+ @Shadow
+ @Final
+ EntityList entityList;
+
+ @Mutable
+ @Shadow
+ @Final
+ private PendingUpdateManager pendingUpdateManager;
+
+ protected MixinClientWorld(MutableWorldProperties properties, RegistryKey registryRef, DynamicRegistryManager registryManager, RegistryEntry dimensionEntry, Supplier profiler, boolean isClient, boolean debugWorld, long biomeAccess, int maxChainedNeighborUpdates) {
+ super(properties, registryRef, registryManager, dimensionEntry, profiler, isClient, debugWorld, biomeAccess, maxChainedNeighborUpdates);
+ }
+
+ @Inject(method = "", at = @At("RETURN"))
+ private void removePendingUpdateManager(ClientPlayNetworkHandler networkHandler, ClientWorld.Properties properties, RegistryKey registryRef, RegistryEntry dimensionTypeEntry, int loadDistance, int simulationDistance, Supplier profiler, WorldRenderer worldRenderer, boolean debugWorld, long seed, CallbackInfo ci) {
+ if (DebugSettings.global().disableSequencing.isEnabled()) {
+ this.pendingUpdateManager = new PendingUpdateManager1_18_2();
+ }
+ }
+
+ /**
+ * @author RK_01
+ * @reason ProtocolHack
+ */
+ @Overwrite
+ public void tickEntity(Entity entity) {
+ entity.resetPosition();
+ final IEntity mixinEntity = (IEntity) entity;
+ if (mixinEntity.viaFabricPlus$isInLoadedChunkAndShouldTick() || entity.isSpectator()) {
+ entity.age++;
+ this.getProfiler().push(() -> Registries.ENTITY_TYPE.getId(entity.getType()).toString());
+ entity.tick();
+ this.getProfiler().pop();
+ }
+ this.checkChunk(entity);
+
+ if (mixinEntity.viaFabricPlus$isInLoadedChunkAndShouldTick()) {
+ for (Entity entity2 : entity.getPassengerList()) {
+ this.tickPassenger(entity, entity2);
+ }
+ }
+ }
+
+ /**
+ * @author RK_01
+ * @reason ProtocolHack
+ */
+ @Overwrite
+ private void tickPassenger(Entity entity, Entity passenger) {
+ if (!passenger.isRemoved() && passenger.getVehicle() == entity) {
+ if (passenger instanceof PlayerEntity || this.entityList.has(passenger)) {
+ final IEntity mixinPassenger = (IEntity) passenger;
+ passenger.resetPosition();
+ if (mixinPassenger.viaFabricPlus$isInLoadedChunkAndShouldTick()) {
+ passenger.age++;
+ passenger.tickRiding();
+ }
+ this.checkChunk(passenger);
+
+ if (mixinPassenger.viaFabricPlus$isInLoadedChunkAndShouldTick()) {
+ for (Entity entity2 : passenger.getPassengerList()) {
+ this.tickPassenger(passenger, entity2);
+ }
+ }
+ }
+ } else {
+ passenger.stopRiding();
+ }
+ }
+
+ @Unique
+ private void checkChunk(Entity entity) {
+ this.getProfiler().push("chunkCheck");
+ final IEntity mixinEntity = (IEntity) entity;
+ final int chunkX = MathHelper.floor(entity.getX() / 16.0D);
+ final int chunkZ = MathHelper.floor(entity.getZ() / 16.0D);
+ if (!mixinEntity.viaFabricPlus$isInLoadedChunkAndShouldTick() || entity.getChunkPos().x != chunkX || entity.getChunkPos().z != chunkZ) {
+ if (!(this.getChunk(chunkX, chunkZ).isEmpty())) {
+ mixinEntity.viaFabricPlus$setInLoadedChunkAndShouldTick(true);
+ }
+ }
+ this.getProfiler().pop();
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinEnchantmentHelper.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinEnchantmentHelper.java
new file mode 100644
index 000000000..ff6c265c7
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinEnchantmentHelper.java
@@ -0,0 +1,50 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
+
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import net.minecraft.enchantment.EnchantmentHelper;
+import net.raphimc.vialoader.util.VersionEnum;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.Constant;
+import org.spongepowered.asm.mixin.injection.ModifyConstant;
+
+@Mixin(EnchantmentHelper.class)
+public abstract class MixinEnchantmentHelper {
+
+ @ModifyConstant(method = "getLevelFromNbt", constant = @Constant(intValue = 0))
+ private static int usePossibleMinLevel(int constant) {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_14_4)) {
+ return Short.MIN_VALUE;
+ }
+
+ return constant;
+ }
+
+ @ModifyConstant(method = "getLevelFromNbt", constant = @Constant(intValue = 255))
+ private static int usePossibleMaxLevel(int constant) {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_14_4)) {
+ return Short.MAX_VALUE;
+ }
+
+ return constant;
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinFlowableFluid.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinFlowableFluid.java
new file mode 100644
index 000000000..44192019b
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinFlowableFluid.java
@@ -0,0 +1,55 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
+
+import de.florianmichael.viafabricplus.fixes.diff.Material1_19_4;
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import net.minecraft.block.*;
+import net.minecraft.fluid.FlowableFluid;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Direction;
+import net.minecraft.world.BlockView;
+import net.raphimc.vialoader.util.VersionEnum;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Redirect;
+
+@Mixin(FlowableFluid.class)
+public abstract class MixinFlowableFluid {
+
+ @Redirect(method = "isFlowBlocked", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;isSideSolidFullSquare(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)Z"))
+ private boolean modifyIsSolidBlock(BlockState instance, BlockView blockView, BlockPos blockPos, Direction direction) {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_11_1to1_11_2)) {
+ return Material1_19_4.getMaterial(instance).solid();
+ } else if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
+ final Block block = instance.getBlock();
+ if (block instanceof ShulkerBoxBlock || block instanceof LeavesBlock || block instanceof TrapdoorBlock ||
+ block == Blocks.BEACON || block == Blocks.CAULDRON || block == Blocks.GLASS ||
+ block == Blocks.GLOWSTONE || block == Blocks.ICE || block == Blocks.SEA_LANTERN ||
+ block instanceof StainedGlassBlock || block == Blocks.PISTON || block == Blocks.STICKY_PISTON ||
+ block == Blocks.PISTON_HEAD || block instanceof StairsBlock) {
+ return false;
+ }
+ }
+
+ return instance.isSideSolidFullSquare(blockView, blockPos, direction);
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinFontStorage.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinFontStorage.java
index 4268150e5..9c4d04643 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinFontStorage.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinFontStorage.java
@@ -19,9 +19,13 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
+import com.llamalad7.mixinextras.sugar.Local;
+import de.florianmichael.viafabricplus.fixes.diff.RenderableGlyphDiff;
import de.florianmichael.viafabricplus.injection.reference.BuiltinEmptyGlyph1_12_2;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
-import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
+import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.*;
import net.minecraft.util.Identifier;
import net.raphimc.vialoader.util.VersionEnum;
@@ -31,97 +35,89 @@
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
-import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
-import java.util.Map;
@Mixin(FontStorage.class)
public abstract class MixinFontStorage {
@Shadow
- protected abstract GlyphRenderer getGlyphRenderer(RenderableGlyph c);
+ private GlyphRenderer blankGlyphRenderer;
@Shadow
- private GlyphRenderer blankGlyphRenderer;
+ protected abstract GlyphRenderer getGlyphRenderer(RenderableGlyph c);
@Shadow
@Final
private Identifier id;
@Unique
- private Map> viaFabricPlus$forbiddenCharacters;
+ private GlyphRenderer blankGlyphRenderer1_12_2;
@Unique
- private boolean viaFabricPlus$obfuscation;
+ private Object2IntMap providedGlyphsCache;
- @Inject(method = "setFonts", at = @At("HEAD"))
- private void trackForbiddenCharacters(List fonts, CallbackInfo ci) {
-// viaFabricPlus$forbiddenCharacters = CharacterMappings.getForbiddenCharactersForID(this.id);
- viaFabricPlus$forbiddenCharacters = new HashMap<>(); // TODO | Fix
+ @Inject(method = "setFonts", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/BuiltinEmptyGlyph;bake(Ljava/util/function/Function;)Lnet/minecraft/client/font/GlyphRenderer;", ordinal = 0))
+ private void bakeBlankGlyph1_12_2(List fonts, CallbackInfo ci) {
+ this.blankGlyphRenderer1_12_2 = BuiltinEmptyGlyph1_12_2.INSTANCE.bake(this::getGlyphRenderer);
+ this.providedGlyphsCache = new Object2IntOpenHashMap<>();
}
- @Unique
- private boolean viaFabricPlus$isForbiddenCharacter(final Font font, final int codePoint) {
- String fontName = null;
- if (font instanceof BitmapFont) {
- fontName = "BitmapFont";
- } else if (font instanceof BlankFont) {
- fontName = "BlankFont";
- } else if (font instanceof SpaceFont) {
- fontName = "SpaceFont";
- } else if (font instanceof UnihexFont) {
- fontName = "UnihexFont";
+ @Inject(method = "findGlyph", at = @At("RETURN"), cancellable = true)
+ private void filterGlyphs1(int codePoint, CallbackInfoReturnable cir, @Local Font font) {
+ if (this.shouldBeInvisible(cir.getReturnValue().equals(FontStorage.GlyphPair.MISSING) ? null : font, codePoint)) {
+ cir.setReturnValue(this.getBlankGlyphPair());
}
- if (fontName == null) return false;
- final var forbiddenCodepoints = viaFabricPlus$forbiddenCharacters.get(fontName);
- if (forbiddenCodepoints == null) return false;
- return forbiddenCodepoints.contains(codePoint);
}
- @Inject(method = "findGlyph", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/Font;getGlyph(I)Lnet/minecraft/client/font/Glyph;"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true)
- private void injectFindGlyph(int codePoint, CallbackInfoReturnable cir, Glyph glyph, Iterator var3, Font font) {
- if (!this.id.getNamespace().equals("minecraft")) return;
-
- if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_4)) {
- if (viaFabricPlus$isForbiddenCharacter(font, codePoint)) cir.setReturnValue(FontStorage.GlyphPair.MISSING);
-
- if (VisualSettings.global().changeFontRendererBehaviour.isEnabled() && cir.getReturnValue() == FontStorage.GlyphPair.MISSING) {
- cir.setReturnValue(new FontStorage.GlyphPair(BuiltinEmptyGlyph1_12_2.VERY_MISSING, BuiltinEmptyGlyph1_12_2.VERY_MISSING));
- }
+ @Inject(method = "findGlyphRenderer", at = @At("RETURN"), cancellable = true)
+ private void filterGlyphs2(int codePoint, CallbackInfoReturnable cir, @Local Font font) {
+ if (this.shouldBeInvisible(cir.getReturnValue().equals(this.blankGlyphRenderer) ? null : font, codePoint)) {
+ cir.setReturnValue(this.getBlankGlyphRenderer());
}
}
- @Inject(method = "findGlyphRenderer", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/Font;getGlyph(I)Lnet/minecraft/client/font/Glyph;"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true)
- private void injectFindGlyphRenderer(int codePoint, CallbackInfoReturnable cir, Iterator var2, Font font) {
- if (!this.id.getNamespace().equals("minecraft")) return;
+ @Inject(method = "findGlyph", at = @At("RETURN"), cancellable = true)
+ private void fixBlankGlyph1_12_2(int codePoint, CallbackInfoReturnable cir) {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2)) {
+ final FontStorage.GlyphPair glyphPair = cir.getReturnValue();
+ final Glyph glyph1 = glyphPair.glyph();
+ final Glyph glyph2 = glyphPair.advanceValidatedGlyph();
+ cir.setReturnValue(new FontStorage.GlyphPair(glyph1 == BuiltinEmptyGlyph.MISSING ? BuiltinEmptyGlyph1_12_2.INSTANCE : glyph1, glyph2 == BuiltinEmptyGlyph.MISSING ? BuiltinEmptyGlyph1_12_2.INSTANCE : glyph2));
+ }
+ }
- if (!viaFabricPlus$obfuscation && ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_4)) {
- if (viaFabricPlus$isForbiddenCharacter(font, codePoint)) cir.setReturnValue(this.blankGlyphRenderer);
+ @Redirect(method = "findGlyphRenderer", at = @At(value = "FIELD", target = "Lnet/minecraft/client/font/FontStorage;blankGlyphRenderer:Lnet/minecraft/client/font/GlyphRenderer;"))
+ private GlyphRenderer fixBlankGlyphRenderer1_12_2(FontStorage instance) {
+ return this.getBlankGlyphRenderer();
+ }
- if (VisualSettings.global().changeFontRendererBehaviour.isEnabled() && cir.getReturnValue() == this.blankGlyphRenderer) {
- cir.setReturnValue(BuiltinEmptyGlyph1_12_2.VERY_MISSING.bake(this::getGlyphRenderer));
- }
+ @Unique
+ private boolean shouldBeInvisible(final Font font, final int codePoint) {
+ if (font != null && this.providedGlyphsCache.computeIfAbsent(font, f -> ((Font) f).getProvidedGlyphs().size()) == 1) {
+ return false; // Probably a custom icon character from a resource pack
}
- }
- /*
- Minecraft uses all characters that exist for obfuscation mode, even those that no longer exist in the selected target version,
- so we must not make the fix in case it is executed from an obfuscated text, because otherwise the obfuscation would have missing characters
- */
+ return (this.id.equals(MinecraftClient.DEFAULT_FONT_ID) || this.id.equals(MinecraftClient.UNICODE_FONT_ID)) && !RenderableGlyphDiff.isGlyphRenderable(codePoint);
+ }
- @Inject(method = "getObfuscatedGlyphRenderer", at = @At("HEAD"))
- private void trackObfuscationState(Glyph glyph, CallbackInfoReturnable cir) {
- viaFabricPlus$obfuscation = true;
+ @Unique
+ private FontStorage.GlyphPair getBlankGlyphPair() {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2)) {
+ return new FontStorage.GlyphPair(BuiltinEmptyGlyph1_12_2.INSTANCE, BuiltinEmptyGlyph1_12_2.INSTANCE);
+ }
+ return FontStorage.GlyphPair.MISSING;
}
- @Inject(method = "getGlyphRenderer(I)Lnet/minecraft/client/font/GlyphRenderer;", at = @At("RETURN"))
- private void revertObfuscationState(int codePoint, CallbackInfoReturnable cir) {
- viaFabricPlus$obfuscation = false;
+ @Unique
+ private GlyphRenderer getBlankGlyphRenderer() {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2)) {
+ return this.blankGlyphRenderer1_12_2;
+ }
+ return this.blankGlyphRenderer;
}
}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinGameOptions.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinGameOptions.java
new file mode 100644
index 000000000..ebc5d27d6
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinGameOptions.java
@@ -0,0 +1,57 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
+
+import de.florianmichael.viafabricplus.ViaFabricPlus;
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import net.minecraft.client.option.GameOptions;
+import net.raphimc.vialoader.util.VersionEnum;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Overwrite;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.ModifyVariable;
+
+@Mixin(GameOptions.class)
+public abstract class MixinGameOptions {
+
+ @Shadow
+ public boolean useNativeTransport;
+
+ @ModifyVariable(method = "setServerViewDistance", at = @At("HEAD"), ordinal = 0, argsOnly = true)
+ private int changeServerViewDistance(int viewDistance) {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_17_1)) return 0;
+ return viewDistance;
+ }
+
+ /**
+ * @author RK_01
+ * @reason Needed as an indicator if the client wants to ping a server or connect to a server
+ */
+ @Overwrite
+ public boolean shouldUseNativeTransport() {
+ if (!this.useNativeTransport) {
+ ViaFabricPlus.global().getLogger().error("Native transport is disabled, but enabling it anyway");
+ }
+
+ return true;
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinGameRenderer.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinGameRenderer.java
new file mode 100644
index 000000000..4aa3428ca
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinGameRenderer.java
@@ -0,0 +1,68 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
+
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.render.GameRenderer;
+import net.minecraft.entity.Entity;
+import net.minecraft.util.hit.BlockHitResult;
+import net.minecraft.util.hit.HitResult;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.MathHelper;
+import net.raphimc.vialoader.util.VersionEnum;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+
+@Mixin(GameRenderer.class)
+public abstract class MixinGameRenderer {
+
+ @Shadow
+ @Final
+ MinecraftClient client;
+
+ @ModifyExpressionValue(method = "updateTargetedEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;raycast(DFZ)Lnet/minecraft/util/hit/HitResult;"))
+ private HitResult bedrockReachAroundRaycast(HitResult hitResult) {
+ if (ProtocolHack.getTargetVersion().equals(VersionEnum.bedrockLatest)) {
+ final Entity entity = this.client.getCameraEntity();
+ if (hitResult.getType() != HitResult.Type.MISS) return hitResult;
+ if (!this.canReachAround(entity)) return hitResult;
+
+ final int x = MathHelper.floor(entity.getX());
+ final int y = MathHelper.floor(entity.getY() - 0.2F);
+ final int z = MathHelper.floor(entity.getZ());
+ final BlockPos floorPos = new BlockPos(x, y, z);
+
+ return new BlockHitResult(floorPos.toCenterPos(), entity.getHorizontalFacing(), floorPos, false);
+ }
+
+ return hitResult;
+ }
+
+ @Unique
+ private boolean canReachAround(final Entity entity) {
+ return entity.isOnGround() && entity.getVehicle() == null && entity.getPitch() >= 45;
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinKeyboard.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinKeyboard.java
new file mode 100644
index 000000000..ac780ada6
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinKeyboard.java
@@ -0,0 +1,60 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
+
+import de.florianmichael.viafabricplus.injection.access.IMouseKeyboard;
+import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
+import net.minecraft.client.Keyboard;
+import net.minecraft.client.MinecraftClient;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Redirect;
+
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+@Mixin(Keyboard.class)
+public abstract class MixinKeyboard implements IMouseKeyboard {
+
+ @Shadow
+ @Final
+ private MinecraftClient client;
+
+ @Unique
+ private final Queue viaFabricPlus$pendingScreenEvents = new ConcurrentLinkedQueue<>();
+
+ @Redirect(method = {"method_22676", "method_22675"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;execute(Ljava/lang/Runnable;)V"))
+ private void storeEvent(MinecraftClient instance, Runnable runnable) {
+ if (this.client.getNetworkHandler() != null && this.client.currentScreen != null && DebugSettings.global().executeInputsInSync.isEnabled()) {
+ this.viaFabricPlus$pendingScreenEvents.offer(runnable);
+ } else {
+ instance.execute(runnable);
+ }
+ }
+
+ @Override
+ public Queue viaFabricPlus$getPendingScreenEvents() {
+ return this.viaFabricPlus$pendingScreenEvents;
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinMinecraftClient.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinMinecraftClient.java
index e77c251e0..e8521bfaa 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinMinecraftClient.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinMinecraftClient.java
@@ -20,34 +20,36 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
-import com.llamalad7.mixinextras.injector.WrapWithCondition;
-import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_12to1_11_1.Protocol1_12To1_11_1;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
-import de.florianmichael.viafabricplus.ViaFabricPlus;
+import de.florianmichael.viafabricplus.fixes.diff.ItemRegistryDiff;
+import de.florianmichael.viafabricplus.injection.access.IMouseKeyboard;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
+import net.minecraft.client.Keyboard;
import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.network.ClientPlayNetworkHandler;
+import net.minecraft.client.Mouse;
import net.minecraft.client.network.ClientPlayerEntity;
-import net.minecraft.client.render.item.HeldItemRenderer;
-import net.minecraft.item.SwordItem;
+import net.minecraft.client.network.ClientPlayerInteractionManager;
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.raphimc.vialoader.util.VersionEnum;
import org.jetbrains.annotations.Nullable;
+import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.Queue;
@Mixin(MinecraftClient.class)
public abstract class MixinMinecraftClient {
@@ -56,58 +58,85 @@ public abstract class MixinMinecraftClient {
@Nullable
public ClientPlayerEntity player;
- @Shadow protected int attackCooldown;
-
- @Shadow @Nullable public abstract ClientPlayNetworkHandler getNetworkHandler();
-
+ @Shadow
+ public int attackCooldown;
- @Unique
- private final ConcurrentLinkedDeque viaFabricPlus$mouseInteractions = new ConcurrentLinkedDeque<>();
+ @Shadow
+ @Final
+ public Mouse mouse;
- @Unique
- private final ConcurrentLinkedDeque viaFabricPlus$keyboardInteractions = new ConcurrentLinkedDeque<>();
+ @Shadow
+ @Final
+ public Keyboard keyboard;
- @SuppressWarnings("ConstantConditions")
- @Inject(method = "tick", at = @At(value = "FIELD", target = "Lnet/minecraft/client/MinecraftClient;currentScreen:Lnet/minecraft/client/gui/screen/Screen;",
- ordinal = 4, shift = At.Shift.BEFORE))
- private void injectTick(CallbackInfo ci) {
- if (!DebugSettings.global().executeInputsInSync.isEnabled()) {
- return;
+ @Redirect(method = "doItemPick", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerInventory;addPickBlock(Lnet/minecraft/item/ItemStack;)V"))
+ private void filterItem(PlayerInventory instance, ItemStack stack) {
+ if (ItemRegistryDiff.keepItem(stack.getItem())) {
+ instance.addPickBlock(stack);
}
+ }
- while (!viaFabricPlus$mouseInteractions.isEmpty()) {
- viaFabricPlus$mouseInteractions.poll().run();
- }
- while (!viaFabricPlus$keyboardInteractions.isEmpty()) {
- viaFabricPlus$keyboardInteractions.poll().run();
+ @Redirect(method = "doItemPick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;clickCreativeStack(Lnet/minecraft/item/ItemStack;I)V"))
+ private void dontSendEmptyItem(ClientPlayerInteractionManager instance, ItemStack stack, int slotId) {
+ if (!stack.isEmpty()) {
+ instance.clickCreativeStack(stack, slotId);
}
}
- @Inject(method = "handleInputEvents", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;hasRidingInventory()Z"))
- private void onInventoryKeyPressed(CallbackInfo ci) {
- if (getNetworkHandler() != null && DebugSettings.global().sendOpenInventoryPacket.isEnabled()) {
- final UserConnection userConnection = ProtocolHack.getPlayNetworkUserConnection();
+ @Redirect(method = "doItemUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/ActionResult;shouldSwingHand()Z", ordinal = 0))
+ private boolean disableSwing(ActionResult instance) {
+ return instance.shouldSwingHand() && ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_15);
+ }
+
+ @Redirect(method = "doItemUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/ActionResult;shouldSwingHand()Z", ordinal = 2))
+ private boolean disableSwing2(ActionResult instance) {
+ return instance.shouldSwingHand() && ProtocolHack.getTargetVersion().isNewerThanOrEqualTo(VersionEnum.r1_15);
+ }
- if (userConnection != null && userConnection.getProtocolInfo().getPipeline().contains(Protocol1_12To1_11_1.class)) {
- final PacketWrapper clientStatus = PacketWrapper.create(ServerboundPackets1_9_3.CLIENT_STATUS, userConnection);
- clientStatus.write(Type.VAR_INT, 2); // Open Inventory Achievement
+ @Redirect(method = "handleInputEvents", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;swingHand(Lnet/minecraft/util/Hand;)V"))
+ private void disableSwing(ClientPlayerEntity instance, Hand hand) {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_14_4)) return;
+ instance.swingHand(hand);
+ }
- try {
- clientStatus.sendToServer(Protocol1_12To1_11_1.class);
- } catch (Exception e) {
- ViaFabricPlus.global().getLogger().error("Failed to send Open Inventory Packet", e);
- }
- }
+ @Inject(method = "tick",
+ at = @At(value = "FIELD", target = "Lnet/minecraft/client/MinecraftClient;currentScreen:Lnet/minecraft/client/gui/screen/Screen;", ordinal = 0, shift = At.Shift.BEFORE),
+ slice = @Slice(
+ from = @At(value = "FIELD", target = "Lnet/minecraft/client/MinecraftClient;attackCooldown:I", ordinal = 0),
+ to = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/Screen;wrapScreenError(Ljava/lang/Runnable;Ljava/lang/String;Ljava/lang/String;)V")
+ )
+ )
+ private void processInputQueues(CallbackInfo ci) {
+ if (DebugSettings.global().executeInputsInSync.isEnabled()) {
+ Queue inputEvents = ((IMouseKeyboard) this.mouse).viaFabricPlus$getPendingScreenEvents();
+ while (!inputEvents.isEmpty()) inputEvents.poll().run();
+
+ inputEvents = ((IMouseKeyboard) this.keyboard).viaFabricPlus$getPendingScreenEvents();
+ while (!inputEvents.isEmpty()) inputEvents.poll().run();
}
}
- @WrapWithCondition(method = "doItemUse",
- slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;interactItem(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/util/Hand;)Lnet/minecraft/util/ActionResult;")),
- at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/item/HeldItemRenderer;resetEquipProgress(Lnet/minecraft/util/Hand;)V", ordinal = 0))
- private boolean removeEquipProgressReset(HeldItemRenderer instance, Hand hand) {
- return ProtocolHack.getTargetVersion().isNewerThan(VersionEnum.r1_8) || !(player.getStackInHand(hand).getItem() instanceof SwordItem);
+ @Inject(method = "handleInputEvents", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/tutorial/TutorialManager;onInventoryOpened()V", shift = At.Shift.AFTER))
+ private void sendOpenInventoryPacket(CallbackInfo ci) throws Exception {
+ if (DebugSettings.global().sendOpenInventoryPacket.isEnabled()) {
+ final PacketWrapper clientStatus = PacketWrapper.create(ServerboundPackets1_9_3.CLIENT_STATUS, ProtocolHack.getPlayNetworkUserConnection());
+ clientStatus.write(Type.VAR_INT, 2); // Open Inventory Achievement
+ clientStatus.scheduleSendToServer(Protocol1_12To1_11_1.class);
+ }
+ }
+
+ @Inject(method = "doAttack", at = @At(value = "FIELD", target = "Lnet/minecraft/client/MinecraftClient;crosshairTarget:Lnet/minecraft/util/hit/HitResult;", shift = At.Shift.BEFORE, ordinal = 0))
+ private void fixSwingPacketOrder(CallbackInfoReturnable cir) {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
+ this.player.swingHand(Hand.MAIN_HAND);
+ }
}
+ @Redirect(method = "doAttack", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;swingHand(Lnet/minecraft/util/Hand;)V"))
+ private void fixSwingPacketOrder(ClientPlayerEntity instance, Hand hand) {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) return;
+ instance.swingHand(Hand.MAIN_HAND);
+ }
@Redirect(method = "tick", at = @At(value = "FIELD", target = "Lnet/minecraft/client/MinecraftClient;attackCooldown:I", ordinal = 1))
private int dontIncrementCooldown(MinecraftClient instance) {
@@ -126,17 +155,6 @@ private void postIncrementCooldown(CallbackInfo ci) {
}
}
- @Redirect(method = "doItemUse",
- slice = @Slice(to = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;interactEntity(Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/entity/Entity;Lnet/minecraft/util/Hand;)Lnet/minecraft/util/ActionResult;")),
- at = @At(value = "INVOKE", target = "Lnet/minecraft/util/ActionResult;isAccepted()Z", ordinal = 0))
- private boolean preventGenericInteract(ActionResult instance) {
- if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_7_6tor1_7_10)) {
- return false;
- }
-
- return instance.isAccepted();
- }
-
@ModifyExpressionValue(method = "handleBlockBreaking", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isUsingItem()Z"))
private boolean allowBlockBreakAndItemUsageAtTheSameTime(boolean original) {
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_7_6tor1_7_10)) {
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinMouse.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinMouse.java
new file mode 100644
index 000000000..9c5bef66a
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinMouse.java
@@ -0,0 +1,73 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
+
+import de.florianmichael.viafabricplus.injection.access.IMouseKeyboard;
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
+import de.florianmichael.viafabricplus.util.MouseSensitivityUtil;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.Mouse;
+import net.minecraft.client.option.SimpleOption;
+import net.raphimc.vialoader.util.VersionEnum;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Redirect;
+
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+@Mixin(Mouse.class)
+public abstract class MixinMouse implements IMouseKeyboard {
+
+ @Shadow
+ @Final
+ private MinecraftClient client;
+
+ @Unique
+ private final Queue viaFabricPlus$pendingScreenEvents = new ConcurrentLinkedQueue<>();
+
+ @Redirect(method = {"method_22684", "method_22685"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;execute(Ljava/lang/Runnable;)V"))
+ private void storeEvent(MinecraftClient instance, Runnable runnable) {
+ if (this.client.getNetworkHandler() != null && this.client.currentScreen != null && DebugSettings.global().executeInputsInSync.isEnabled()) {
+ this.viaFabricPlus$pendingScreenEvents.offer(runnable);
+ } else {
+ instance.execute(runnable);
+ }
+ }
+
+ @Redirect(method = "updateMouse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/option/SimpleOption;getValue()Ljava/lang/Object;", ordinal = 0))
+ private Object adjustMouseSensitivity1_13_2(SimpleOption instance) {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_13_2)) {
+ return (double) MouseSensitivityUtil.get1_13SliderValue(instance.getValue().floatValue()).keyFloat();
+ }
+
+ return instance.getValue();
+ }
+
+ @Override
+ public Queue viaFabricPlus$getPendingScreenEvents() {
+ return this.viaFabricPlus$pendingScreenEvents;
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinPlayerInventory.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinPlayerInventory.java
new file mode 100644
index 000000000..c62a36aaa
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinPlayerInventory.java
@@ -0,0 +1,62 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
+
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import net.minecraft.entity.player.PlayerInventory;
+import net.minecraft.util.collection.DefaultedList;
+import net.raphimc.vialoader.util.VersionEnum;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Redirect;
+import org.spongepowered.asm.mixin.injection.Slice;
+
+import java.util.AbstractList;
+
+@Mixin(PlayerInventory.class)
+public abstract class MixinPlayerInventory {
+
+ @Redirect(method = "", slice = @Slice(from = @At(value = "CONSTANT", args = "intValue=1")), at = @At(value = "INVOKE", target = "Lnet/minecraft/util/collection/DefaultedList;ofSize(ILjava/lang/Object;)Lnet/minecraft/util/collection/DefaultedList;", ordinal = 0))
+ private DefaultedList redirectOffhandInventory(int size, T def) {
+ if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
+ //noinspection MixinInnerClass
+ return new DefaultedList<>(new AbstractList() {
+ @Override
+ public T get(int index) {
+ return def;
+ }
+
+ @Override
+ public T set(int index, T element) {
+ return def;
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+ }, def) {
+ };
+ }
+
+ return DefaultedList.ofSize(size, def);
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinPendingUpdateManager.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinRedirectResolver.java
similarity index 62%
rename from src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinPendingUpdateManager.java
rename to src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinRedirectResolver.java
index 48c6f9068..cb9b75d40 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinPendingUpdateManager.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinRedirectResolver.java
@@ -19,20 +19,25 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
-import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
-import net.minecraft.client.network.PendingUpdateManager;
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import net.minecraft.client.network.RedirectResolver;
+import net.minecraft.client.network.ServerAddress;
+import net.raphimc.vialoader.util.VersionEnum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-@Mixin(PendingUpdateManager.class)
-public abstract class MixinPendingUpdateManager {
+import javax.naming.directory.DirContext;
+import java.util.Optional;
- @Inject(method = "incrementSequence", at = @At(value = "FIELD", target = "Lnet/minecraft/client/network/PendingUpdateManager;pendingSequence:Z", shift = At.Shift.BEFORE), cancellable = true)
- private void injectIncrementSequence(CallbackInfoReturnable cir) {
- if (DebugSettings.global().disableSequencing.isEnabled()) {
- cir.setReturnValue((PendingUpdateManager) (Object) this);
+@Mixin(RedirectResolver.class)
+public interface MixinRedirectResolver {
+
+ @Inject(method = "method_36911", at = @At("HEAD"), cancellable = true)
+ private static void disableSrvForPre1_3(DirContext context, ServerAddress address, CallbackInfoReturnable> cir) {
+ if (ProtocolHack.getTargetVersion().isOlderThan(VersionEnum.r1_3_1tor1_3_2)) {
+ cir.setReturnValue(Optional.empty());
}
}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinServerAddress.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinServerAddress.java
new file mode 100644
index 000000000..bb190605b
--- /dev/null
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinServerAddress.java
@@ -0,0 +1,47 @@
+/*
+ * This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
+ * Copyright (C) 2021-2023 FlorianMichael/EnZaXD
+ * Copyright (C) 2023 RK_01/RaphiMC and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
+
+import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
+import net.minecraft.client.network.AllowedAddressResolver;
+import net.minecraft.client.network.ServerAddress;
+import net.raphimc.vialoader.util.VersionEnum;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+@Mixin(ServerAddress.class)
+public abstract class MixinServerAddress {
+
+ @Shadow
+ @Final
+ private static ServerAddress INVALID;
+
+ @Inject(method = "parse", at = @At("RETURN"), cancellable = true)
+ private static void resolveSrv(String address, CallbackInfoReturnable cir) {
+ if (!cir.getReturnValue().equals(INVALID) && ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_4tor1_16_5)) {
+ cir.setReturnValue(AllowedAddressResolver.DEFAULT.redirectResolver.lookupRedirect(cir.getReturnValue()).orElse(cir.getReturnValue()));
+ }
+ }
+
+}
diff --git a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinServerResourcePackProvider.java b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinServerResourcePackProvider.java
index 04a464a42..eee9a8f98 100644
--- a/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinServerResourcePackProvider.java
+++ b/src/main/java/de/florianmichael/viafabricplus/injection/mixin/fixes/minecraft/MixinServerResourcePackProvider.java
@@ -22,6 +22,7 @@
import com.google.common.hash.HashCode;
import com.google.common.hash.Hashing;
import com.google.common.io.Files;
+import com.llamalad7.mixinextras.sugar.Local;
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
import net.minecraft.GameVersion;
import net.minecraft.SharedConstants;
@@ -29,7 +30,6 @@
import net.raphimc.vialoader.util.VersionEnum;
import org.apache.commons.codec.digest.DigestUtils;
import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
@@ -45,9 +45,6 @@
@Mixin(ServerResourcePackProvider.class)
public abstract class MixinServerResourcePackProvider {
- @Unique
- private File viaFabricPlus$trackedFile;
-
@Redirect(method = "getDownloadHeaders", at = @At(value = "INVOKE", target = "Lnet/minecraft/SharedConstants;getGameVersion()Lnet/minecraft/GameVersion;"))
private static GameVersion editHeaders() {
// return PackFormatsMappings.current();
@@ -68,23 +65,16 @@ private static void removeHeaders(CallbackInfoReturnable