{"id":15013292,"url":"https://github.com/viaversionmcp/viamcp","last_synced_at":"2026-03-16T07:34:28.207Z","repository":{"id":166596474,"uuid":"642073207","full_name":"ViaVersionMCP/ViaMCP","owner":"ViaVersionMCP","description":"Client-side Implementation of the Via* projects for MCP","archived":false,"fork":false,"pushed_at":"2024-12-30T23:16:08.000Z","size":42941,"stargazers_count":61,"open_issues_count":7,"forks_count":10,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-09T22:12:29.838Z","etag":null,"topics":["forge","hackclient","java","mcp","meteor","minecraft","minecraftcoderpack","versionswitcher","viabackwards","viamcp","viarewind","viaversion"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ViaVersionMCP.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-17T19:01:00.000Z","updated_at":"2025-03-27T19:20:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"f709d32f-56f3-4598-94b4-3f8808fe4907","html_url":"https://github.com/ViaVersionMCP/ViaMCP","commit_stats":{"total_commits":33,"total_committers":4,"mean_commits":8.25,"dds":"0.12121212121212122","last_synced_commit":"d919fe7d9cba87c0a55fc2a1d311da23d0ffd211"},"previous_names":["florianmichael/viamcp","viaversionmcp/viamcp"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ViaVersionMCP%2FViaMCP","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ViaVersionMCP%2FViaMCP/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ViaVersionMCP%2FViaMCP/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ViaVersionMCP%2FViaMCP/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ViaVersionMCP","download_url":"https://codeload.github.com/ViaVersionMCP/ViaMCP/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248119294,"owners_count":21050755,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["forge","hackclient","java","mcp","meteor","minecraft","minecraftcoderpack","versionswitcher","viabackwards","viamcp","viarewind","viaversion"],"created_at":"2024-09-24T19:44:02.773Z","updated_at":"2026-03-16T07:34:28.133Z","avatar_url":"https://github.com/ViaVersionMCP.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ViaMCP\nViaVersion VersionSwitcher for Minecraft Coder Pack (MCP)\n\n\u003c!-- TOC --\u003e\n* [ViaMCP](#viamcp)\n  * [Contact](#contact)\n  * [Setup](#setup)\n    * [Main-Class](#main-class)\n    * [NetworkManager](#networkmanager)\n  * [Version Control](#version-control)\n    * [Version Slider](#version-slider)\n  * [Clientside Fixes](#clientside-fixes)\n    * [Attack Order Fixes](#attack-order-fixes)\n    * [Block Sound Fixes](#block-sound-fixes)\n    * [Transaction Fixes for 1.17+](#transaction-fixes-for-117)\n  * [Sending raw packets (e.g 1.9 interactions)](#sending-raw-packets-eg-19-interactions)\n  * [Exporting Without JAR Files](#exporting-without-jar-files)\n\u003c!-- TOC --\u003e\n## Contact\nIf you encounter any issues, please report them on the\n[issue tracker](https://github.com/FlorianMichael/ViaMCP/issues).  \nIf you just want to talk or need help with ViaMCP feel free to join my\n[Discord](https://discord.gg/BwWhCHUKDf).\n\n# Updating notice for existing users (if you are new to ViaMCP, you can ignore this)\nViaVersion 4.10.0 did some changes to the ProtocolVersion API, you have to update your own code if you ever used the ViaLoadingBase class:\n```java\n// Old\nViaLoadingBase.getInstance().getTargetVersion().isOlderThan(ProtocolVersion.v1_8);\nViaLoadingBase.getInstance().getTargetVersion().isNewerThan(ProtocolVersion.v1_8);\nViaLoadingBase.getInstance().getTargetVersion().isNewerThanOrEqualTo(ProtocolVersion.v1_8);\nViaLoadingBase.getInstance().getTargetVersion().isOlderThanOrEqualTo(ProtocolVersion.v1_8);\n\nViaLoadingBase.getInstance().getTargetVersion().getIndex();\n\n// New\nViaLoadingBase.getInstance().getTargetVersion().olderThan(ProtocolVersion.v1_8);\nViaLoadingBase.getInstance().getTargetVersion().newerThan(ProtocolVersion.v1_8);\nViaLoadingBase.getInstance().getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_8);\nViaLoadingBase.getInstance().getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8);\n\nViaLoadingBase.PROTOCOLS.indexOf(ViaLoadingBase.getInstance().getTargetVersion());\n```\nIn addition to that, the *ComparableProtocolVersion* class has been removed and it's methods have been moved to the *ProtocolVersion* class.\n\n## Setup\nFirstly, you will need to add the listed libraries into your dependencies in IntelliJ or Eclipse\n\nDependencies (Included inside ``libraries`` folder)\n```\nViaVersion-[ver]-downgraded.jar \u003e ViaVersion \u003e https://github.com/ViaVersion/ViaVersion\nViaBackwards-[ver]-downgraded.jar \u003e ViaBackwards \u003e https://github.com/ViaVersion/ViaBackwards\nViaRewind-[ver]-downgraded.jar \u003e ViaRewind \u003e https://github.com/ViaVersion/ViaRewind\n```\n\nSecondly, you need to add code that allows you to actually use ViaMCP (**Choose the version folder that corresponds with your client version**)\n\nFor other versions than 1.8.x and 1.12.2, you will need to modify the code to fit your client version. You can see namings for\nother major versions [here](https://github.com/ViaVersion/ViaForge)\n\nNOTE:\nViaVersion 5.0.0+ doesn't support Java 8 anymore, therefore when updating the libraries yourself, you need to download\nthe -Java8 jar files from the [ci server](https://ci.viaversion.com/) or generate them yourself using [this](https://github.com/ViaVersion/ViaForge/tree/legacy-1.8?tab=readme-ov-file#installation) tool.\n\n### Main-Class\nAdd this to the main class of your client (aka injection function)\n\n```java\ntry {\n    ViaMCP.create();\n    \n    // In case you want a version slider like in the Minecraft options, you can use this code here, please choose one of those:\n          \n    ViaMCP.INSTANCE.initAsyncSlider(); // For top left aligned slider\n    ViaMCP.INSTANCE.initAsyncSlider(x, y, width (min. 110), height (recommended 20)); // For custom position and size slider\n} catch (Exception e) {\n    e.printStackTrace();\n}\n```\n\n### NetworkManager\nYou will need to modify 2 methods inside NetworkManager.java\n\n**1. Hook ViaVersion into the Netty Pipeline**\n\nFind the method, that is ``func_181124_a``, ``createNetworkManagerAndConnect`` or contains ``(Bootstrap)((Bootstrap)((Bootstrap)(new Bootstrap()).group((EventLoopGroup)lazyloadbase.getValue())``\n\nFind the vanilla network pipeline call:\n```java\n// 1.8.x client\np_initChannel_1_.pipeline().addLast((String)\"timeout\", (ChannelHandler)(new ReadTimeoutHandler(30))).addLast((String)\"splitter\", (ChannelHandler)(new MessageDeserializer2())).addLast((String)\"decoder\", (ChannelHandler)(new MessageDeserializer(EnumPacketDirection.CLIENTBOUND))).addLast((String)\"prepender\", (ChannelHandler)(new MessageSerializer2())).addLast((String)\"encoder\", (ChannelHandler)(new MessageSerializer(EnumPacketDirection.SERVERBOUND))).addLast((String)\"packet_handler\", (ChannelHandler)networkmanager);\n\n// 1.12.x client\np_initChannel_1_.pipeline().addLast(\"timeout\", new ReadTimeoutHandler(30)).addLast(\"splitter\", new NettyVarint21FrameDecoder()).addLast(\"decoder\", new NettyPacketDecoder(EnumPacketDirection.CLIENTBOUND)).addLast(\"prepender\", new NettyVarint21FrameEncoder()).addLast(\"encoder\", new NettyPacketEncoder(EnumPacketDirection.SERVERBOUND)).addLast(\"packet_handler\", networkmanager);\n```\n\nAfter the vanilla network pipeline call, add the ViaMCP protocol pipeline hook:\n```java\nif (p_initChannel_1_ instanceof SocketChannel \u0026\u0026 ViaLoadingBase.getInstance().getTargetVersion().getVersion() != ViaMCP.NATIVE_VERSION) {\n    final UserConnection user = new UserConnectionImpl(p_initChannel_1_, true);\n    new ProtocolPipelineImpl(user);\n    \n    p_initChannel_1_.pipeline().addLast(new MCPVLBPipeline(user));\n}\n```\n\nYour code should look like this afterwards (1.8.x for example), the vanilla network pipeline call should not be commented out and the ViaMCP protocol pipeline hook should be after the vanilla network pipeline call:\n```java\np_initChannel_1_.pipeline().addLast((String)\"timeout\", (ChannelHandler)(new ReadTimeoutHandler(30))).addLast((String)\"splitter\", (ChannelHandler)(new MessageDeserializer2())).addLast((String)\"decoder\", (ChannelHandler)(new MessageDeserializer(EnumPacketDirection.CLIENTBOUND))).addLast((String)\"prepender\", (ChannelHandler)(new MessageSerializer2())).addLast((String)\"encoder\", (ChannelHandler)(new MessageSerializer(EnumPacketDirection.SERVERBOUND))).addLast((String)\"packet_handler\", (ChannelHandler)networkmanager);\n\nif (p_initChannel_1_ instanceof SocketChannel \u0026\u0026 ViaLoadingBase.getInstance().getTargetVersion().getVersion() != ViaMCP.NATIVE_VERSION) {\n    final UserConnection user = new UserConnectionImpl(p_initChannel_1_, true);\n    new ProtocolPipelineImpl(user);\n    \n    p_initChannel_1_.pipeline().addLast(new MCPVLBPipeline(user));\n}\n```\n###### Side note: If you want to send custom packets, you have to store the UserConnection instance in a variable for later, it's important that this variable is NOT STATIC since it's also used for pinging servers!\n\n**2. Fix the compression in the NetworkManager#setCompressionTreshold function**\n\nSimply call the following code at the end of the method in Minecraft:\n```java\nthis.channel.pipeline().fireUserEventTriggered(new CompressionReorderEvent());\n```\n\n## Version Control\nYou will need to add a button to access the protocol switcher (or alternatively use the version slider under this section) \u003cbr\u003e\nIn ``addSingleplayerMultiplayerButtons()`` function add (if in GuiMainMenu):\n```java\nthis.buttonList.add(new GuiButton(69, 5, 5, 90, 20, \"Version\"));\n```\nIn ``actionPerformed()`` function add:\n```java\nif (button.id == 69)\n{\n    this.mc.displayGuiScreen(new GuiProtocolSelector(this));\n}\n```\n### Version Slider\nYou can also use a version slider to control ViaMCP versions\n```java\nthis.buttonList.add(ViaMCP.INSTANCE.getAsyncVersionSlider());\n```\n\n## Clientside Fixes\n### Attack Order Fixes\n**Class: Minecraft.java** \u003cbr\u003e\n**Function: clickMouse()** \u003cbr\u003e\n\n**1.8.x** \u003cbr\u003e\nReplace ``this.thePlayer.swingItem();`` on the 1st line in the if-clause with:\n```java\nAttackOrder.sendConditionalSwing(this.objectMouseOver);\n```\nReplace ``this.playerController.attackEntity(this.thePlayer, this.objectMouseOver.entityHit);`` in the switch in case ``ENTITY`` with:\n```java\nAttackOrder.sendFixedAttack(this.thePlayer, this.objectMouseOver.entityHit);\n```\n\n**1.12.2** \u003cbr\u003e\nReplace ``this.player.swingArm(EnumHand.MAIN_HAND);`` at the last line in the else if-clause with:\n```java\nAttackOrder.sendConditionalSwing(this.objectMouseOver, EnumHand.MAIN_HAND);\n```\nReplace ``this.playerController.attackEntity(this.player, this.objectMouseOver.entityHit);`` in the switch in case ``ENTITY`` with:\n```java\nAttackOrder.sendFixedAttack(this.thePlayer, this.objectMouseOver.entityHit, EnumHand.MAIN_HAND);\n```\n\n### Block Sound Fixes\n**Block Placement**\n\nReplace all code in ``onItemUse`` function in the ``ItemBlock`` class with:\n```java\nreturn FixedSoundEngine.onItemUse(this, stack, playerIn, worldIn, pos, side, hitX, hitY, hitZ);\n```\n\n**Block Breaking**\n\nReplace all code in ``destroyBlock`` function in the ``World`` class with:\n```java\nreturn FixedSoundEngine.destroyBlock(this, pos, dropBlock);\n```\n\n### Transaction Fixes for 1.17+\nCall the ``fixTransactions();`` in the ``ViaMCP`` class file so ViaVersion doesn't remap anything in transaction packets.\n\nAfter that, you need to do some changes in the Game code:\n\n**Class: S32PacketConfirmTransaction.java** \u003cbr\u003e\n**Function: readPacketData()** \u003cbr\u003e\n\nReplace the code with this method:\n```java\npublic void readPacketData(PacketBuffer buf) throws IOException {\n    if (ViaLoadingBase.getInstance().getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_17)) {\n        this.windowId = buf.readInt();\n    } else {\n        this.windowId = buf.readUnsignedByte();\n        this.actionNumber = buf.readShort();\n        this.accepted = buf.readBoolean();\n    }\n}\n```\n\n**Class: C0FPacketConfirmTransaction.java** \u003cbr\u003e\n**Function: writePacketData()** \u003cbr\u003e\n\nReplace the code with this method:\n```java\npublic void writePacketData(PacketBuffer buf) throws IOException {\n    if (ViaLoadingBase.getInstance().getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_17)) {\n        buf.writeInt(this.windowId);\n    } else {\n        buf.writeByte(this.windowId);\n        buf.writeShort(this.uid);\n        buf.writeByte(this.accepted ? 1 : 0);\n    }\n}\n```\n\nNote: this code can be different depending on your mappings and game version, you just need to make sure\nit only reads the window id and doesn't read the rest of the packet because we previously removed the \nViaVersion handlers which would have handled the rest of the packet.\n\n**Class: NetHandlerPlayClient.java** \u003cbr\u003e\n**Function: handleConfirmTransaction()** \u003cbr\u003e\n \nAdd this code after the checkThreadAndEnqueue function call:\n```java\nif (ViaLoadingBase.getInstance().getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_17)) {\n    this.addToSendQueue(new C0FPacketConfirmTransaction(packetIn.getWindowId(), 0, false));\n    return;\n}\n```\n\n## Sending raw packets (e.g 1.9 interactions)\nYou can send raw packets with ViaMCP, you can use the following code to send raw packets:\n```java\nfinal PacketWrapper blockPlace = PacketWrapper.create(ServerboundPackets1_9.PLAYER_BLOCK_PLACEMENT, null); // Replace null with your stored UserConnection, see NetworkManager tutorial above\nblockPlace.write(Type.POSITION1_8, new Position(0, 0, 0)); // Replace with the block position\nblockPlace.write(Type.VAR_INT, 0); // Replace with the block face, see https://wiki.vg/index.php?title=Protocol\u0026oldid=7617#Player_Digging\nblockPlace.write(Type.VAR_INT, 0); // Replace with the hand, 0 for main hand, 1 for off hand\nblockPlace.write(Type.UNSIGNED_BYTE, (short) 0); // The x pos of the crosshair, from 0 to 15 increasing from west to east\nblockPlace.write(Type.UNSIGNED_BYTE, (short) 0); // The y pos of the crosshair, from 0 to 15 increasing from bottom to top\nblockPlace.write(Type.UNSIGNED_BYTE, (short) 0); // The z pos of the crosshair, from 0 to 15 increasing from north to south\n\ntry {\n    blockPlace.sendToServer(Protocol1_9To1_8.class); // Protocol class names are: server -\u003e client version\n} catch (Exception e) {\n    // Packet sending failed\n    throw new RuntimeException(e);\n}\n```\n\n## Exporting Without JAR Files\nThis should fix most peoples issues with dependencies (usually NoClassDefFoundError or ClassNotFoundException)\n\n- First export your client normally\n- Open your client .jar file with an archive program (winrar or 7zip for example)\n- Also open all libraries with the selected archive program (ViaVersion, ViaBackwards, ViaRewind and SnakeYaml)\n- From ViaVersion, ViaBackwards and ViaRewind drag and drop ``assets``, ``com`` and ``us`` folders to your client .jar\n- Then save and close, now your client should be working correctly ;)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviaversionmcp%2Fviamcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fviaversionmcp%2Fviamcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviaversionmcp%2Fviamcp/lists"}