Token导航 LogoToken导航TokenDH.com
Via MCP logo
运维云端未说明官方级别未说明来源级核验

Via MCP

MCP Server

ViaMCP是一个用于Minecraft Coder Pack (MCP)的版本切换工具,支持多版本协议兼容和客户端修复。

工具数

0

提示词数

0

GitHub Stars

10

资源数

0
Java云端部署Docker

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

ViaVersionMCP

提供方

ViaVersionMCP

最后核验

2026/5/17 20:19

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

ViaMCP 公司

ViaVersion版本切换器用于Minecraft编码器包(MCP)

- 设置 - 主要班级 - 网络管理器 - 版本控制 - 版本滑块 - 客户端修复 - 攻击顺序修复 - 阻止声音修复 - 1.17的交易修复+ - 1.21.2的客户端勾选修复+ - Hypixel加入修复 - 发送原始数据包(例如1.9交互) - 导出时不使用JAR文件

现有用户的更新通知(如果您是ViaMCP的新手,可以忽略此通知)

ViaVersion 4.10.0对ProtocolVersion API进行了一些更改,如果您使用过ViaLoadingBase类,则必须更新您自己的代码:

// Old
ViaLoadingBase.getInstance().getTargetVersion().isOlderThan(ProtocolVersion.v1_8);
ViaLoadingBase.getInstance().getTargetVersion().isNewerThan(ProtocolVersion.v1_8);
ViaLoadingBase.getInstance().getTargetVersion().isNewerThanOrEqualTo(ProtocolVersion.v1_8);
ViaLoadingBase.getInstance().getTargetVersion().isOlderThanOrEqualTo(ProtocolVersion.v1_8);

ViaLoadingBase.getInstance().getTargetVersion().getIndex();

// New
ViaLoadingBase.getInstance().getTargetVersion().olderThan(ProtocolVersion.v1_8);
ViaLoadingBase.getInstance().getTargetVersion().newerThan(ProtocolVersion.v1_8);
ViaLoadingBase.getInstance().getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_8);
ViaLoadingBase.getInstance().getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8);

ViaLoadingBase.PROTOCOLS.indexOf(ViaLoadingBase.getInstance().getTargetVersion());

除此之外 *可比协议版本* 类已被删除,其方法已被移动到 *协议版本* 类。

设置

首先,您需要将列出的库添加到IntelliJ或Eclipse中的依赖项中

依赖关系(包括在内 libraries 文件夹)

ViaVersion-[ver]-downgraded.jar > ViaVersion > https://github.com/ViaVersion/ViaVersion
ViaBackwards-[ver]-downgraded.jar > ViaBackwards > https://github.com/ViaVersion/ViaBackwards
ViaRewind-[ver]-downgraded.jar > ViaRewind > https://github.com/ViaVersion/ViaRewind

其次,您需要添加允许您实际使用ViaMCP的代码(选择与客户端版本对应的版本文件夹)

对于1.8.x和1.12.2以外的其他版本,您需要修改代码以适应您的客户端版本。你可以看到以下名称 其他主要版本 这里

注: ViaVersion 5.0.0+不再支持Java 8,因此在自己更新库时,您需要下载

主要班级

将其添加到客户端的主类中(也称为注入函数)

try {
    ViaMCP.create();
    
    // In case you want a version slider like in the Minecraft options, you can use this code here, please choose one of those:
          
    ViaMCP.INSTANCE.initAsyncSlider(); // For top left aligned slider
    ViaMCP.INSTANCE.initAsyncSlider(x, y, width (min. 110), height (recommended 20)); // For custom position and size slider
} catch (Exception e) {
    e.printStackTrace();
}

网络管理器

您需要修改NetworkManager.java中的2个方法

1.将ViaVersion钩入Netty管道

找到方法,即 func_181124_a, createNetworkManagerAndConnect 或包含 (Bootstrap)((Bootstrap)((Bootstrap)(new Bootstrap()).group((EventLoopGroup)lazyloadbase.getValue())

查找vanilla网络管道调用:

// 1.8.x client
p_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);

// 1.12.x client
p_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);

在vanilla网络管道调用后,添加ViaMCP协议管道挂钩:

if (p_initChannel_1_ instanceof SocketChannel && ViaLoadingBase.getInstance().getTargetVersion().getVersion() != ViaMCP.NATIVE_VERSION) {
    final UserConnection user = new UserConnectionImpl(p_initChannel_1_, true);
    new ProtocolPipelineImpl(user);
    
    p_initChannel_1_.pipeline().addLast(new MCPVLBPipeline(user));
}

之后你的代码应该看起来像这样(例如1.8.x),vanilla网络管道调用不应该被注释掉,ViaMCP协议管道钩子应该在vanilla网路管道调用之后:

p_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);

if (p_initChannel_1_ instanceof SocketChannel && ViaLoadingBase.getInstance().getTargetVersion().getVersion() != ViaMCP.NATIVE_VERSION) {
    final UserConnection user = new UserConnectionImpl(p_initChannel_1_, true);
    new ProtocolPipelineImpl(user);
    
    p_initChannel_1_.pipeline().addLast(new MCPVLBPipeline(user));
}

旁注:如果你想发送自定义数据包,你必须将UserConnection实例存储在一个变量中以备后用,重要的是这个变量不是静态的,因为它也用于ping服务器!

2.修复NetworkManager#setCompressionTreshold函数中的压缩问题

只需在Minecraft的方法末尾调用以下代码:

this.channel.pipeline().fireUserEventTriggered(new CompressionReorderEvent());

版本控制

您需要添加一个按钮来访问协议切换器(或者使用本节下的版本滑块)

addSingleplayerMultiplayerButtons() 功能添加(如果在GuiMainMenu中):

this.buttonList.add(new GuiButton(69, 5, 5, 90, 20, "Version"));

actionPerformed() 功能添加:

if (button.id == 69)
{
    this.mc.displayGuiScreen(new GuiProtocolSelector(this));
}

版本滑块

您还可以使用版本滑块来控制ViaMCP版本

this.buttonList.add(ViaMCP.INSTANCE.getAsyncVersionSlider());

客户端修复

攻击顺序修复

类别:Minecraft.java

功能:点击鼠标()

1.8.x

替换 this.thePlayer.swingItem(); if条款第1行:

AttackOrder.sendConditionalSwing(this.objectMouseOver);

替换 this.playerController.attackEntity(this.thePlayer, this.objectMouseOver.entityHit); 在开关的情况下 ENTITY 与:

AttackOrder.sendFixedAttack(this.thePlayer, this.objectMouseOver.entityHit);

1.12.2

替换 this.player.swingArm(EnumHand.MAIN_HAND); 在else if子句的最后一行:

AttackOrder.sendConditionalSwing(this.objectMouseOver, EnumHand.MAIN_HAND);

替换 this.playerController.attackEntity(this.player, this.objectMouseOver.entityHit); 在开关的情况下 ENTITY 与:

AttackOrder.sendFixedAttack(this.thePlayer, this.objectMouseOver.entityHit, EnumHand.MAIN_HAND);

阻止声音修复

区块布局

替换中的所有代码 onItemUse 功能在 ItemBlock 类与:

return FixedSoundEngine.onItemUse(this, stack, playerIn, worldIn, pos, side, hitX, hitY, hitZ);

断块

替换中的所有代码 destroyBlock 功能在 World 类与:

return FixedSoundEngine.destroyBlock(this, pos, dropBlock);

1.17的交易修复+

打电话给 fixTransactions();ViaMCP 类文件,因此ViaVersion不会重新映射事务数据包中的任何内容。 之后,您需要对游戏代码进行一些更改:

类:S32PacketConfirmTransaction.java

函数:readPacketData()

用以下方法替换代码:

public void readPacketData(PacketBuffer buf) throws IOException {
    if (ViaLoadingBase.getInstance().getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_17)) {
        this.windowId = buf.readInt();
    } else {
        this.windowId = buf.readUnsignedByte();
        this.actionNumber = buf.readShort();
        this.accepted = buf.readBoolean();
    }
}

类:C0FPacketConfirmTransaction.java

函数:writePacketData()

用以下方法替换代码:

public void writePacketData(PacketBuffer buf) throws IOException {
    if (ViaLoadingBase.getInstance().getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_17)) {
        buf.writeInt(this.windowId);
    } else {
        buf.writeByte(this.windowId);
        buf.writeShort(this.uid);
        buf.writeByte(this.accepted ? 1 : 0);
    }
}

注意:此代码可能因映射和游戏版本而异,您只需确保 它只读取窗口id,不读取数据包的其余部分,因为我们之前删除了 ViaVersion处理程序会处理数据包的其余部分。

类:NetHandlerPlayClient.java

函数:handleConfirmTransaction()

在checkThreadAndEnqueue函数调用后添加以下代码:

if (ViaLoadingBase.getInstance().getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_17)) {
    this.addToSendQueue(new C0FPacketConfirmTransaction(packetIn.getWindowId(), 0, false));
    return;
}

1.21.2的客户端勾选修复+

在函数末尾插入以下代码 runTick() 在课堂上 Minecraft:

if (ViaLoadingBase.getInstance().getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_21_2)) {
    UserConnection connection = Via.getManager().getConnectionManager().getConnections().iterator().next();
	PacketWrapper packet = PacketWrapper.create(ServerboundPackets1_21_2.CLIENT_TICK_END, null, connection);
	packet.sendToServer(Protocol1_21_2To1_21.class);
}

Hypixel加入修复

打电话给 fixHypixelLogin();ViaMCP 类文件

然后在头部插入以下代码 runTick() 类中的函数 Minecraft:

PacketWrapperImpl packet = null;
PacketWrapperImpl packetInfo = null;
int modelParts = 0;
// Hypixel only allow 1.21.4+ client to login.
if (ViaLoadingBase.getInstance().getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_21_4)) {
	packet = (PacketWrapperImpl) PacketWrapper.create(ServerboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD, ViaMCP.INSTANCE.user);
	packet.write(Types.STRING, "minecraft:brand");
	packet.write(Types.STRING, "vanilla");
	packet.sendToServer(Protocol1_20_3To1_20_2.class);
		                    
	packetInfo = (PacketWrapperImpl) PacketWrapper.create(ServerboundConfigurationPackets1_20_2.CLIENT_INFORMATION, ViaMCP.INSTANCE.user);
	packetInfo.write(Types.STRING, Minecraft.getMinecraft().gameSettings.language.toLowerCase());
	packetInfo.write(Types.BYTE, (byte) Minecraft.getMinecraft().gameSettings.renderDistanceChunks);
	packetInfo.write(Types.VAR_INT, Minecraft.getMinecraft().gameSettings.chatVisibility.ordinal());
	packetInfo.write(Types.BOOLEAN, Minecraft.getMinecraft().gameSettings.chatColours);
		                    
	for (EnumPlayerModelParts parts : Minecraft.getMinecraft().gameSettings.getModelParts()) {
	    modelParts |= parts.getPartMask();
	}
		                    
	packetInfo.write(Types.UNSIGNED_BYTE, (short) modelParts);
	packetInfo.write(Types.VAR_INT, 1);
	packetInfo.write(Types.BOOLEAN, true);
	packetInfo.write(Types.BOOLEAN, true);
	packetInfo.sendToServer(Protocol1_20_3To1_20_2.class);
}

发送原始数据包(例如1.9交互)

您可以使用ViaMCP发送原始数据包,您可以使用以下代码发送原始数据包包送:

final PacketWrapper blockPlace = PacketWrapper.create(ServerboundPackets1_9.PLAYER_BLOCK_PLACEMENT, null); // Replace null with your stored UserConnection, see NetworkManager tutorial above
blockPlace.write(Type.POSITION1_8, new Position(0, 0, 0)); // Replace with the block position
blockPlace.write(Type.VAR_INT, 0); // Replace with the block face, see https://wiki.vg/index.php?title=Protocol&oldid=7617#Player_Digging
blockPlace.write(Type.VAR_INT, 0); // Replace with the hand, 0 for main hand, 1 for off hand
blockPlace.write(Type.UNSIGNED_BYTE, (short) 0); // The x pos of the crosshair, from 0 to 15 increasing from west to east
blockPlace.write(Type.UNSIGNED_BYTE, (short) 0); // The y pos of the crosshair, from 0 to 15 increasing from bottom to top
blockPlace.write(Type.UNSIGNED_BYTE, (short) 0); // The z pos of the crosshair, from 0 to 15 increasing from north to south

try {
    blockPlace.sendToServer(Protocol1_9To1_8.class); // Protocol class names are: server -> client version
} catch (Exception e) {
    // Packet sending failed
    throw new RuntimeException(e);
}

导出时不使用JAR文件

这应该可以解决大多数人的依赖关系问题(通常是NoClassDefFoundError或ClassNotFoundException)

  • 首先正常导出您的客户
  • 使用归档程序(例如winrar或7zip)打开您的客户端.jar文件
  • 还可以使用所选的存档程序(ViaVersion、ViaBackwards、ViaRewind和SnakeYaml)打开所有库
  • 从ViaVersion、ViaBackwards和ViaRewind拖放 assets, comus 将文件夹添加到client.jar
  • 然后保存并关闭,现在您的客户端应该正常工作了;)

目录标签

目录标签

Java云端部署DockerMinecraft本地部署版本切换协议兼容客户端修复游戏开发

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

session

工具数量(toolCount,工具数)

0

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明session部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP