diff --git a/README.md b/README.md index db46610..e265728 100644 --- a/README.md +++ b/README.md @@ -1,268 +1,5 @@ # ViaMCP ViaVersion VersionSwitcher for Minecraft Coder Pack (MCP) - -* [ViaMCP](#viamcp) - * [Contact](#contact) - * [Setup](#setup) - * [Main-Class](#main-class) - * [NetworkManager](#networkmanager) - * [Version Control](#version-control) - * [Version Slider](#version-slider) - * [Clientside Fixes](#clientside-fixes) - * [Attack Order Fixes](#attack-order-fixes) - * [Block Sound Fixes](#block-sound-fixes) - * [Transaction Fixes for 1.17+](#transaction-fixes-for-117) - * [Exporting Without JAR Files](#exporting-without-jar-files) - -## Contact -If you encounter any issues, please report them on the -[issue tracker](https://github.com/FlorianMichael/ViaMCP/issues). -If you just want to talk or need help with ViaMCP feel free to join my -[Discord](https://discord.gg/BwWhCHUKDf). - -# Updating notice for existing users (if you are new to ViaMCP, you can ignore this) -ViaVersion 4.10.0 did some changes to the ProtocolVersion API, you have to update your own code if you ever used the ViaLoadingBase class: -```java -// 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()); -``` -In addition to that, the *ComparableProtocolVersion* class has been removed and it's methods have been moved to the *ProtocolVersion* class. - -## Setup -Firstly, you will need to add the listed libraries into your dependencies in IntelliJ or Eclipse - -Dependencies (Included inside ``libraries`` folder) -``` -downgraded-ViaVersion-[ver].jar > ViaVersion > https://github.com/ViaVersion/ViaVersion -downgraded-ViaBackwards-[ver].jar > ViaBackwards > https://github.com/ViaVersion/ViaBackwards -downgraded-ViaRewind-[ver].jar > ViaRewind > https://github.com/ViaVersion/ViaRewind -snakeyml-2.2.jar > SnakeYaml > https://bitbucket.org/snakeyaml/snakeyaml -``` - -Secondly, you need to add code that allows you to actually use ViaMCP (**Choose the version folder that corresponds with your client version**) - -For 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 -other major versions [here](https://github.com/ViaVersion/ViaForge) - -NOTE: -ViaVersion 5.0.0+ doesn't support Java 8 anymore, therefore when updating the libraries yourself, you need to download -the -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. - -### Main-Class -Add this to the main class of your client (aka injection function) - -```java -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 -You will need to modify 2 methods inside NetworkManager.java - -**1. Hook ViaVersion into the Netty Pipeline** - -Find the method, that is ``func_181124_a``, ``createNetworkManagerAndConnect`` or contains ``(Bootstrap)((Bootstrap)((Bootstrap)(new Bootstrap()).group((EventLoopGroup)lazyloadbase.getValue())`` - -Find the vanilla network pipeline call: -```java -// 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); -``` - -After the vanilla network pipeline call, add the ViaMCP protocol pipeline hook: -```java -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)); -} -``` - -Your 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: -```java -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)); -} -``` - -### 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! - -**2. Fix the compression in the NetworkManager#setCompressionTreshold function** - -Simply call the following code at the end of the method in Minecraft: -```java -this.channel.pipeline().fireUserEventTriggered(new CompressionReorderEvent()); -``` - -## Version Control -You will need to add a button to access the protocol switcher (or alternatively use the version slider under this section)
-In ``addSingleplayerMultiplayerButtons()`` function add (if in GuiMainMenu): -```java -this.buttonList.add(new GuiButton(69, 5, 5, 90, 20, "Version")); -``` -In ``actionPerformed()`` function add: -```java -if (button.id == 69) -{ - this.mc.displayGuiScreen(new GuiProtocolSelector(this)); -} -``` -### Version Slider -You can also use a version slider to control ViaMCP versions -```java -this.buttonList.add(ViaMCP.INSTANCE.getAsyncVersionSlider()); -``` - -## Clientside Fixes -### Attack Order Fixes -**Class: Minecraft.java**
-**Function: clickMouse()**
- -**1.8.x**
-Replace ``this.thePlayer.swingItem();`` on the 1st line in the if-clause with: -```java -AttackOrder.sendConditionalSwing(this.objectMouseOver); -``` -Replace ``this.playerController.attackEntity(this.thePlayer, this.objectMouseOver.entityHit);`` in the switch in case ``ENTITY`` with: -```java -AttackOrder.sendFixedAttack(this.thePlayer, this.objectMouseOver.entityHit); -``` - -**1.12.2**
-Replace ``this.player.swingArm(EnumHand.MAIN_HAND);`` at the last line in the else if-clause with: -```java -AttackOrder.sendConditionalSwing(this.objectMouseOver, EnumHand.MAIN_HAND); -``` -Replace ``this.playerController.attackEntity(this.player, this.objectMouseOver.entityHit);`` in the switch in case ``ENTITY`` with: -```java -AttackOrder.sendFixedAttack(this.thePlayer, this.objectMouseOver.entityHit, EnumHand.MAIN_HAND); -``` - -### Block Sound Fixes -**Block Placement** - -Replace all code in ``onItemUse`` function in the ``ItemBlock`` class with: -```java -return FixedSoundEngine.onItemUse(this, stack, playerIn, worldIn, pos, side, hitX, hitY, hitZ); -``` - -**Block Breaking** - -Replace all code in ``destroyBlock`` function in the ``World`` class with: -```java -return FixedSoundEngine.destroyBlock(this, pos, dropBlock); -``` - -### Transaction Fixes for 1.17+ -Call the ``fixTransactions();`` in the ``ViaMCP`` class file so ViaVersion doesn't remap anything in transaction packets. - -After that, you need to do some changes in the Game code: - -**Class: S32PacketConfirmTransaction.java**
-**Function: readPacketData()**
- -Replace the code with this method: -```java -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(); - } -} -``` - -**Class: C0FPacketConfirmTransaction.java**
-**Function: writePacketData()**
- -Replace the code with this method: -```java -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); - } -} -``` - -Note: this code can be different depending on your mappings and game version, you just need to make sure -it only reads the window id and doesn't read the rest of the packet because we previously removed the -ViaVersion handlers which would have handled the rest of the packet. - -**Class: NetHandlerPlayClient.java**
-**Function: handleConfirmTransaction()**
- -Add this code after the checkThreadAndEnqueue function call: -```java -if (ViaLoadingBase.getInstance().getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_17)) { - this.addToSendQueue(new C0FPacketConfirmTransaction(packetIn.getWindowId(), 0, false)); - return; -} -``` - -## Sending raw packets (e.g 1.9 interactions) -You can send raw packets with ViaMCP, you can use the following code to send raw packets: -```java -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); -} -``` - -## Exporting Without JAR Files -This should fix most peoples issues with dependencies (usually NoClassDefFoundError or ClassNotFoundException) - -- First export your client normally -- Open your client .jar file with an archive program (winrar or 7zip for example) -- Also open all libraries with the selected archive program (ViaVersion, ViaBackwards, ViaRewind and SnakeYaml) -- From ViaBackwards drag and drop ``assets`` and ``com`` folders to your client .jar -- From ViaRewind drag and drop ``assets`` and ``de`` folders to your client .jar -- From ViaSnakeYaml drag and drop ``org`` folder to your client .jar -- From ViaVersion drag and drop ``assets``, ``com`` and ``us`` folders to your client .jar -- Then save and close, now your client should be working correctly ;) +[if you want to use MCP Reborn >= 1.20.x](/v1.20.x) +[else if you are using MCP 1.8.x || 1.12.x click here](/v1.8.x) \ No newline at end of file diff --git a/v1.20.2/.gitignore b/v1.20.2/.gitignore new file mode 100644 index 0000000..f68d109 --- /dev/null +++ b/v1.20.2/.gitignore @@ -0,0 +1,29 @@ +### IntelliJ IDEA ### +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/v1.20.2/README.md b/v1.20.2/README.md new file mode 100644 index 0000000..3b0cf5e --- /dev/null +++ b/v1.20.2/README.md @@ -0,0 +1,54 @@ + +### Main-Class +Add this to the main class of your client (aka injection function) + +```java +try { + ViaMCP.create(); +} catch (Exception e) { + e.printStackTrace(); +} +``` + + +### Connection +You will need to modify 2 methods inside ``net.minecraft.network.Connection.java`` + +**1. Hook ViaVersion into the Netty Pipeline** + +Find the method, that is ``m_264299_``, ``configureSerialization`` + +Find the vanilla network pipeline call: +```java +p_265436_.addLast("splitter", new Varint21FrameDecoder(p_299297_)).addLast("decoder", new PacketDecoder(attributekey)).addLast("prepender", new Varint21LengthFieldPrepender()).addLast("encoder", new PacketEncoder(attributekey1)).addLast("unbundler", new PacketBundleUnpacker(attributekey1)).addLast("bundler", new PacketBundlePacker(attributekey)); +``` + +After the vanilla network pipeline call, add the ViaMCP protocol pipeline hook: +```java +if(p_265436_.channel() instanceof SocketChannel && ViaLoadingBase.getInstance().getTargetVersion().getVersion() != ViaMCP.NATIVE_VERSION) { + final UserConnection user = new UserConnectionImpl(p_265436_.channel(), p_265104_ == PacketFlow.CLIENTBOUND); + new ProtocolPipelineImpl(user); + + p_265436_.addLast(new MCPVLBPipeline(user)); +} +``` + +**2. Fix the compression in the net.minecraft.network.Connection#setupCompression function** + +Simply call the following code at the end of the method in Minecraft: +```java +this.channel.pipeline().fireUserEventTriggered(new CompressionReorderEvent()); +``` + +## Version Control +You will need to add a button to access the protocol switcher ~~(or alternatively use the version slider under this section)~~
+In ``createNormalMenuOptions()`` function add (if in TitleScreen): + + +add this to the bottom of the method: +```java +this.addRenderableWidget(Button.builder(Component.text("Version"), (button) -> { + assert this.minecraft != null; + this.minecraft.setScreen(new GuiProtocolSelector(Minecraft.getInstance().screen)); +}).bounds(5, 5, 90, 20).build()); +``` \ No newline at end of file diff --git a/v1.20.2/src/florianmichael/vialoadingbase/ViaLoadingBase.java b/v1.20.2/src/florianmichael/vialoadingbase/ViaLoadingBase.java new file mode 100644 index 0000000..2cbc7a8 --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/ViaLoadingBase.java @@ -0,0 +1,252 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase; + +import com.viaversion.viaversion.ViaManagerImpl; +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.platform.providers.ViaProviders; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import com.viaversion.viaversion.libs.gson.JsonObject; +import com.viaversion.viaversion.protocol.ProtocolManagerImpl; +import de.florianmichael.vialoadingbase.model.Platform; +import de.florianmichael.vialoadingbase.platform.ViaBackwardsPlatformImpl; +import de.florianmichael.vialoadingbase.platform.ViaRewindPlatformImpl; +import de.florianmichael.vialoadingbase.platform.viaversion.VLBViaCommandHandler; +import de.florianmichael.vialoadingbase.platform.viaversion.VLBViaProviders; +import de.florianmichael.vialoadingbase.platform.ViaVersionPlatformImpl; +import de.florianmichael.vialoadingbase.platform.viaversion.VLBViaInjector; +import de.florianmichael.vialoadingbase.util.JLoggerToLog4j; +import org.apache.logging.log4j.LogManager; +import slice.Slice; + +import java.io.File; +import java.util.*; +import java.util.function.BooleanSupplier; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.logging.Logger; + +public class ViaLoadingBase { + public final static String VERSION = "${vialoadingbase_version}"; + public final static Logger LOGGER = new JLoggerToLog4j(LogManager.getLogger("ViaLoadingBase")); + + public final static Platform PSEUDO_VIA_VERSION = new Platform("ViaVersion", () -> true, () -> { + // Empty + }, protocolVersions -> protocolVersions.addAll(ViaVersionPlatformImpl.createVersionList())); + public final static Platform PLATFORM_VIA_BACKWARDS = new Platform("ViaBackwards", () -> inClassPath("com.viaversion.viabackwards.api.ViaBackwardsPlatform"), () -> new ViaBackwardsPlatformImpl(Via.getManager().getPlatform().getDataFolder())); + public final static Platform PLATFORM_VIA_REWIND = new Platform("ViaRewind", () -> inClassPath("com.viaversion.viarewind.api.ViaRewindPlatform"), () -> new ViaRewindPlatformImpl(Via.getManager().getPlatform().getDataFolder())); + + public final static List PROTOCOLS = new ArrayList<>(); + + private static ViaLoadingBase instance; + + private final LinkedList platforms; + private final File runDirectory; + private final int nativeVersion; + private final BooleanSupplier forceNativeVersionCondition; + private final Supplier dumpSupplier; + private final Consumer providers; + private final Consumer managerBuilderConsumer; + private final Consumer onProtocolReload; + + private ProtocolVersion nativeProtocolVersion; + private ProtocolVersion targetProtocolVersion; + + public ViaLoadingBase(LinkedList platforms, File runDirectory, int nativeVersion, BooleanSupplier forceNativeVersionCondition, Supplier dumpSupplier, Consumer providers, Consumer managerBuilderConsumer, Consumer onProtocolReload) { + this.platforms = platforms; + + this.runDirectory = new File(runDirectory, "ViaLoadingBase"); + this.nativeVersion = nativeVersion; + this.forceNativeVersionCondition = forceNativeVersionCondition; + this.dumpSupplier = dumpSupplier; + this.providers = providers; + this.managerBuilderConsumer = managerBuilderConsumer; + this.onProtocolReload = onProtocolReload; + + instance = this; + initPlatform(); + } + + public ProtocolVersion getTargetVersion() { + if (forceNativeVersionCondition != null && forceNativeVersionCondition.getAsBoolean()) return nativeProtocolVersion; + + return targetProtocolVersion; + } + + public void reload(final ProtocolVersion protocolVersion) { + if(protocolVersion == null) return; + + this.targetProtocolVersion = protocolVersion; + + if (this.onProtocolReload != null) this.onProtocolReload.accept(targetProtocolVersion); + + Slice.INSTANCE.logger.info("ViaLoadingBase has reloaded to {} ({})", targetProtocolVersion.getName(), targetProtocolVersion.getVersion()); + } + + public void initPlatform() { + for (Platform platform : platforms) platform.createProtocolPath(); + + this.nativeProtocolVersion = ProtocolVersion.getProtocol(this.nativeVersion); + this.targetProtocolVersion = this.nativeProtocolVersion; + + final ViaVersionPlatformImpl viaVersionPlatform = new ViaVersionPlatformImpl(ViaLoadingBase.LOGGER); + final ViaManagerImpl.ViaManagerBuilder builder = ViaManagerImpl.builder(). + platform(viaVersionPlatform). + loader(new VLBViaProviders()). + injector(new VLBViaInjector()). + commandHandler(new VLBViaCommandHandler()) + ; + + if (this.managerBuilderConsumer != null) this.managerBuilderConsumer.accept(builder); + + Via.init(builder.build()); + + final ViaManagerImpl manager = (ViaManagerImpl) Via.getManager(); + manager.addEnableListener(() -> { + for (Platform platform : this.platforms) platform.build(ViaLoadingBase.LOGGER); + }); + + manager.init(); + manager.onServerLoaded(); + manager.getProtocolManager().setMaxProtocolPathSize(Integer.MAX_VALUE); + manager.getProtocolManager().setMaxPathDeltaIncrease(-1); + ((ProtocolManagerImpl) manager.getProtocolManager()).refreshVersions(); + + ViaLoadingBase.LOGGER.info("ViaLoadingBase has loaded " + Platform.COUNT + "/" + platforms.size() + " platforms"); + } + + public static ViaLoadingBase getInstance() { + return instance; + } + + public List getSubPlatforms() { + return platforms; + } + + public File getRunDirectory() { + return runDirectory; + } + + public int getNativeVersion() { + return nativeVersion; + } + + public Supplier getDumpSupplier() { + return dumpSupplier; + } + + public Consumer getProviders() { + return providers; + } + + public static boolean inClassPath(final String name) { + try { + Class.forName(name); + return true; + } catch (Exception ignored) { + return false; + } + } + + @Deprecated + public static List getProtocols() { + return PROTOCOLS; + } + + public static class ViaLoadingBaseBuilder { + private final LinkedList platforms = new LinkedList<>(); + + private File runDirectory; + private Integer nativeVersion; + private BooleanSupplier forceNativeVersionCondition; + private Supplier dumpSupplier; + private Consumer providers; + private Consumer managerBuilderConsumer; + private Consumer onProtocolReload; + + public ViaLoadingBaseBuilder() { + platforms.add(PSEUDO_VIA_VERSION); + + platforms.add(PLATFORM_VIA_BACKWARDS); + platforms.add(PLATFORM_VIA_REWIND); + } + + public static ViaLoadingBaseBuilder create() { + return new ViaLoadingBaseBuilder(); + } + + public ViaLoadingBaseBuilder platform(final Platform platform) { + this.platforms.add(platform); + return this; + } + + public ViaLoadingBaseBuilder platform(final Platform platform, final int position) { + this.platforms.add(position, platform); + return this; + } + + public ViaLoadingBaseBuilder runDirectory(final File runDirectory) { + this.runDirectory = runDirectory; + return this; + } + + public ViaLoadingBaseBuilder nativeVersion(final int nativeVersion) { + this.nativeVersion = nativeVersion; + return this; + } + + public ViaLoadingBaseBuilder forceNativeVersionCondition(final BooleanSupplier forceNativeVersionCondition) { + this.forceNativeVersionCondition = forceNativeVersionCondition; + return this; + } + + public ViaLoadingBaseBuilder dumpSupplier(final Supplier dumpSupplier) { + this.dumpSupplier = dumpSupplier; + return this; + } + + public ViaLoadingBaseBuilder providers(final Consumer providers) { + this.providers = providers; + return this; + } + + public ViaLoadingBaseBuilder managerBuilderConsumer(final Consumer managerBuilderConsumer) { + this.managerBuilderConsumer = managerBuilderConsumer; + return this; + } + + public ViaLoadingBaseBuilder onProtocolReload(final Consumer onProtocolReload) { + this.onProtocolReload = onProtocolReload; + return this; + } + + public void build() { + if (ViaLoadingBase.getInstance() != null) { + ViaLoadingBase.LOGGER.severe("ViaLoadingBase has already started the platform!"); + return; + } + if (runDirectory == null || nativeVersion == null) { + ViaLoadingBase.LOGGER.severe("Please check your ViaLoadingBaseBuilder arguments!"); + return; + } + + ViaLoadingBase.instance = new ViaLoadingBase(platforms, runDirectory, nativeVersion, forceNativeVersionCondition, dumpSupplier, providers, managerBuilderConsumer, onProtocolReload); + } + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/command/UserCommandSender.java b/v1.20.2/src/florianmichael/vialoadingbase/command/UserCommandSender.java new file mode 100644 index 0000000..cf9bd4a --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/command/UserCommandSender.java @@ -0,0 +1,53 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.command; + +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.command.ViaCommandSender; +import com.viaversion.viaversion.api.connection.UserConnection; + +import java.util.UUID; + +public class UserCommandSender implements ViaCommandSender { + private final UserConnection user; + + public UserCommandSender(UserConnection user) { + this.user = user; + } + + @Override + public boolean hasPermission(String s) { + return false; + } + + @Override + public void sendMessage(String s) { + Via.getPlatform().sendMessage(getUUID(), s); + } + + @Override + public UUID getUUID() { + return user.getProtocolInfo().getUuid(); + } + + @Override + public String getName() { + return user.getProtocolInfo().getUsername(); + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/model/Platform.java b/v1.20.2/src/florianmichael/vialoadingbase/model/Platform.java new file mode 100644 index 0000000..e97e59a --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/model/Platform.java @@ -0,0 +1,72 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.model; + +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import de.florianmichael.vialoadingbase.ViaLoadingBase; + +import java.util.List; +import java.util.function.BooleanSupplier; +import java.util.function.Consumer; +import java.util.logging.Logger; + +public class Platform { + public static int COUNT = 0; + + private final String name; + private final BooleanSupplier load; + private final Runnable executor; + private final Consumer> versionCallback; + + public Platform(String name, BooleanSupplier load, Runnable executor) { + this(name, load, executor, null); + } + + public Platform(String name, BooleanSupplier load, Runnable executor, Consumer> versionCallback) { + this.name = name; + this.load = load; + this.executor = executor; + this.versionCallback = versionCallback; + } + + public String getName() { + return name; + } + + public void createProtocolPath() { + if (this.versionCallback != null) { + this.versionCallback.accept(ViaLoadingBase.PROTOCOLS); + } + } + + public void build(final Logger logger) { + if (this.load.getAsBoolean()) { + try { + this.executor.run(); + logger.info("Loaded Platform " + this.name); + COUNT++; + } catch (Throwable t) { + logger.severe("An error occurred while loading Platform " + this.name + ":"); + t.printStackTrace(); + } + return; + } + logger.severe("Platform " + this.name + " is not present"); + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/model/ProtocolRange.java b/v1.20.2/src/florianmichael/vialoadingbase/model/ProtocolRange.java new file mode 100644 index 0000000..7598b07 --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/model/ProtocolRange.java @@ -0,0 +1,62 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.model; + +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; + +@Deprecated +public class ProtocolRange { + private final ProtocolVersion lowerBound; + private final ProtocolVersion upperBound; + + public ProtocolRange(ProtocolVersion lowerBound, ProtocolVersion upperBound) { + if (lowerBound == null && upperBound == null) { + throw new RuntimeException("Invalid protocol range"); + } + this.lowerBound = lowerBound; + this.upperBound = upperBound; + } + + public static ProtocolRange andNewer(final ProtocolVersion version) { + return new ProtocolRange(null, version); + } + + public static ProtocolRange singleton(final ProtocolVersion version) { + return new ProtocolRange(version, version); + } + + public static ProtocolRange andOlder(final ProtocolVersion version) { + return new ProtocolRange(version, null); + } + + public boolean contains(final ProtocolVersion protocolVersion) { + if (this.lowerBound != null && protocolVersion.olderThan(lowerBound)) return false; + + return this.upperBound == null || protocolVersion.olderThanOrEqualTo(upperBound); + } + + @Override + public String toString() { + if (lowerBound == null) return upperBound.getName() + "+"; + if (upperBound == null) return lowerBound.getName() + "-"; + if (lowerBound == upperBound) return lowerBound.getName(); + + return lowerBound.getName() + " - " + upperBound.getName(); + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/netty/VLBPipeline.java b/v1.20.2/src/florianmichael/vialoadingbase/netty/VLBPipeline.java new file mode 100644 index 0000000..5d1e67b --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/netty/VLBPipeline.java @@ -0,0 +1,87 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.netty; + +import com.viaversion.viaversion.api.connection.UserConnection; +import de.florianmichael.vialoadingbase.netty.event.CompressionReorderEvent; +import de.florianmichael.vialoadingbase.netty.handler.VLBViaDecodeHandler; +import de.florianmichael.vialoadingbase.netty.handler.VLBViaEncodeHandler; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +public abstract class VLBPipeline extends ChannelInboundHandlerAdapter { + public final static String VIA_DECODER_HANDLER_NAME = "via-decoder"; + public final static String VIA_ENCODER_HANDLER_NAME = "via-encoder"; + + private final UserConnection user; + + public VLBPipeline(final UserConnection user) { + this.user = user; + } + + @Override + public void handlerAdded(ChannelHandlerContext ctx) throws Exception { + super.handlerAdded(ctx); + + ctx.pipeline().addBefore(getDecoderHandlerName(), VIA_DECODER_HANDLER_NAME, this.createVLBViaDecodeHandler()); + ctx.pipeline().addBefore(getEncoderHandlerName(), VIA_ENCODER_HANDLER_NAME, this.createVLBViaEncodeHandler()); + } + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + super.userEventTriggered(ctx, evt); + + if (evt instanceof CompressionReorderEvent) { + final int decoderIndex = ctx.pipeline().names().indexOf(getDecompressionHandlerName()); + if (decoderIndex == -1) return; + + if (decoderIndex > ctx.pipeline().names().indexOf(VIA_DECODER_HANDLER_NAME)) { + final ChannelHandler decoder = ctx.pipeline().get(VIA_DECODER_HANDLER_NAME); + final ChannelHandler encoder = ctx.pipeline().get(VIA_ENCODER_HANDLER_NAME); + + ctx.pipeline().remove(decoder); + ctx.pipeline().remove(encoder); + + ctx.pipeline().addAfter(getDecompressionHandlerName(), VIA_DECODER_HANDLER_NAME, decoder); + ctx.pipeline().addAfter(getCompressionHandlerName(), VIA_ENCODER_HANDLER_NAME, encoder); + } + } + } + + public VLBViaDecodeHandler createVLBViaDecodeHandler() { + return new VLBViaDecodeHandler(this.user); + } + + public VLBViaEncodeHandler createVLBViaEncodeHandler() { + return new VLBViaEncodeHandler(this.user); + } + + public abstract String getDecoderHandlerName(); + + public abstract String getEncoderHandlerName(); + + public abstract String getDecompressionHandlerName(); + + public abstract String getCompressionHandlerName(); + + public UserConnection getUser() { + return user; + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/netty/event/CompressionReorderEvent.java b/v1.20.2/src/florianmichael/vialoadingbase/netty/event/CompressionReorderEvent.java new file mode 100644 index 0000000..daa82a6 --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/netty/event/CompressionReorderEvent.java @@ -0,0 +1,22 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.netty.event; + +public class CompressionReorderEvent { +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/netty/handler/VLBViaDecodeHandler.java b/v1.20.2/src/florianmichael/vialoadingbase/netty/handler/VLBViaDecodeHandler.java new file mode 100644 index 0000000..9731a1e --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/netty/handler/VLBViaDecodeHandler.java @@ -0,0 +1,71 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.netty.handler; + +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.protocol.packet.State; +import com.viaversion.viaversion.exception.CancelCodecException; +import com.viaversion.viaversion.exception.CancelDecoderException; +import com.viaversion.viaversion.exception.InformativeException; +import com.viaversion.viaversion.util.PipelineUtil; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageDecoder; + +import java.util.List; + +@ChannelHandler.Sharable +public class VLBViaDecodeHandler extends MessageToMessageDecoder { + private final UserConnection user; + + public VLBViaDecodeHandler(UserConnection user) { + this.user = user; + } + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List out) throws Exception { + if (!user.checkIncomingPacket()) throw CancelDecoderException.generate(null); + if (!user.shouldTransformPacket()) { + out.add(bytebuf.retain()); + return; + } + + ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf); + try { + user.transformIncoming(transformedBuf, CancelDecoderException::generate); + + out.add(transformedBuf.retain()); + } finally { + transformedBuf.release(); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if (PipelineUtil.containsCause(cause, CancelCodecException.class)) return; + + if ((PipelineUtil.containsCause(cause, InformativeException.class) + && user.getProtocolInfo().getServerState() != State.HANDSHAKE) + || Via.getManager().debugHandler().enabled()) { + cause.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/v1.20.2/src/florianmichael/vialoadingbase/netty/handler/VLBViaEncodeHandler.java b/v1.20.2/src/florianmichael/vialoadingbase/netty/handler/VLBViaEncodeHandler.java new file mode 100644 index 0000000..4733304 --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/netty/handler/VLBViaEncodeHandler.java @@ -0,0 +1,63 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.netty.handler; + +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.exception.CancelCodecException; +import com.viaversion.viaversion.exception.CancelEncoderException; +import com.viaversion.viaversion.util.PipelineUtil; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToMessageEncoder; + +import java.util.List; + +@ChannelHandler.Sharable +public class VLBViaEncodeHandler extends MessageToMessageEncoder { + private final UserConnection user; + + public VLBViaEncodeHandler(UserConnection user) { + this.user = user; + } + + @Override + protected void encode(final ChannelHandlerContext ctx, ByteBuf bytebuf, List out) throws Exception { + if (!user.checkOutgoingPacket()) throw CancelEncoderException.generate(null); + if (!user.shouldTransformPacket()) { + out.add(bytebuf.retain()); + return; + } + + ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf); + try { + user.transformOutgoing(transformedBuf, CancelEncoderException::generate); + + out.add(transformedBuf.retain()); + } finally { + transformedBuf.release(); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if (PipelineUtil.containsCause(cause, CancelCodecException.class)) return; + super.exceptionCaught(ctx, cause); + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/platform/ViaBackwardsPlatformImpl.java b/v1.20.2/src/florianmichael/vialoadingbase/platform/ViaBackwardsPlatformImpl.java new file mode 100644 index 0000000..abe287e --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/platform/ViaBackwardsPlatformImpl.java @@ -0,0 +1,51 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.platform; + +import com.viaversion.viabackwards.api.ViaBackwardsPlatform; +import de.florianmichael.vialoadingbase.ViaLoadingBase; + +import java.io.File; +import java.util.logging.Logger; + +public class ViaBackwardsPlatformImpl implements ViaBackwardsPlatform { + private final File directory; + + public ViaBackwardsPlatformImpl(final File directory) { + this.init(new File(this.directory = directory, "viabackwards.yml")); + } + + @Override + public Logger getLogger() { + return ViaLoadingBase.LOGGER; + } + + @Override + public boolean isOutdated() { + return false; + } + + @Override + public void disable() {} + + @Override + public File getDataFolder() { + return directory; + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/platform/ViaRewindPlatformImpl.java b/v1.20.2/src/florianmichael/vialoadingbase/platform/ViaRewindPlatformImpl.java new file mode 100644 index 0000000..c844379 --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/platform/ViaRewindPlatformImpl.java @@ -0,0 +1,44 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.platform; + +import com.viaversion.viarewind.api.ViaRewindPlatform; +import de.florianmichael.vialoadingbase.ViaLoadingBase; + +import java.io.File; +import java.util.logging.Logger; + +public class ViaRewindPlatformImpl implements ViaRewindPlatform { + + private final File directory; + + public ViaRewindPlatformImpl(final File directory) { + this.init(new File(this.directory = directory, "viarewind.yml")); + } + + @Override + public Logger getLogger() { + return ViaLoadingBase.LOGGER; + } + + @Override + public File getDataFolder() { + return this.directory; + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/platform/ViaVersionPlatformImpl.java b/v1.20.2/src/florianmichael/vialoadingbase/platform/ViaVersionPlatformImpl.java new file mode 100644 index 0000000..a7c1ad4 --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/platform/ViaVersionPlatformImpl.java @@ -0,0 +1,178 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.platform; + +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.ViaAPI; +import com.viaversion.viaversion.api.command.ViaCommandSender; +import com.viaversion.viaversion.api.configuration.ViaVersionConfig; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.platform.UnsupportedSoftware; +import com.viaversion.viaversion.api.platform.ViaPlatform; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import com.viaversion.viaversion.libs.gson.JsonObject; +import com.viaversion.viaversion.util.VersionInfo; +import de.florianmichael.vialoadingbase.ViaLoadingBase; +import de.florianmichael.vialoadingbase.platform.viaversion.VLBViaAPIWrapper; +import de.florianmichael.vialoadingbase.platform.viaversion.VLBViaConfig; +import de.florianmichael.vialoadingbase.util.VLBTask; + +import java.io.File; +import java.util.*; +import java.util.concurrent.*; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +public class ViaVersionPlatformImpl implements ViaPlatform { + + private final ViaAPI api = new VLBViaAPIWrapper(); + + private final Logger logger; + private final VLBViaConfig config; + + public ViaVersionPlatformImpl(final Logger logger) { + this.logger = logger; + config = new VLBViaConfig(new File(ViaLoadingBase.getInstance().getRunDirectory(), "viaversion.yml"), logger); + } + + public static List createVersionList() { + final List versions = new ArrayList<>(ProtocolVersion.getProtocols()).stream().filter(version -> version.newerThanOrEqualTo(ProtocolVersion.v1_8)).collect(Collectors.toList()); + Collections.reverse(versions); + return versions; + } + + @Override + public ViaCommandSender[] getOnlinePlayers() { + return new ViaCommandSender[0]; + } + + @Override + public void sendMessage(UUID uuid, String msg) { + if (uuid == null) { + this.getLogger().info(msg); + } else { + this.getLogger().info("[" + uuid + "] " + msg); + } + } + + @Override + public boolean kickPlayer(UUID uuid, String s) { + return false; + } + + @Override + public boolean disconnect(UserConnection connection, String message) { + return ViaPlatform.super.disconnect(connection, message); + } + + @Override + public VLBTask runAsync(Runnable runnable) { + return new VLBTask(Via.getManager().getScheduler().execute(runnable)); + } + + @Override + public VLBTask runRepeatingAsync(Runnable runnable, long ticks) { + return new VLBTask(Via.getManager().getScheduler().scheduleRepeating(runnable, 0, ticks * 50, TimeUnit.MILLISECONDS)); + } + + @Override + public VLBTask runSync(Runnable runnable) { + return this.runAsync(runnable); + } + + @Override + public VLBTask runSync(Runnable runnable, long ticks) { + return new VLBTask(Via.getManager().getScheduler().schedule(runnable, ticks * 50, TimeUnit.MILLISECONDS)); + } + + @Override + public VLBTask runRepeatingSync(Runnable runnable, long ticks) { + return this.runRepeatingAsync(runnable, ticks); + } + + @Override + public boolean isProxy() { + return true; + } + + @Override + public void onReload() { + } + + @Override + public Logger getLogger() { + return this.logger; + } + + @Override + public ViaVersionConfig getConf() { + return config; + } + + @Override + public ViaAPI getApi() { + return api; + } + + @Override + public File getDataFolder() { + return ViaLoadingBase.getInstance().getRunDirectory(); + } + + @Override + public String getPluginVersion() { + return VersionInfo.VERSION; + } + + @Override + public String getPlatformName() { + return "ViaLoadingBase"; + } + + @Override + public String getPlatformVersion() { + return ViaLoadingBase.VERSION; + } + + @Override + public boolean isPluginEnabled() { + return true; + } + + public VLBViaConfig getConfig() { + return config; + } + + @Override + public Collection getUnsupportedSoftwareClasses() { + return ViaPlatform.super.getUnsupportedSoftwareClasses(); + } + + @Override + public boolean hasPlugin(String s) { + return false; + } + + @Override + public JsonObject getDump() { + if (ViaLoadingBase.getInstance().getDumpSupplier() == null) return new JsonObject(); + + return ViaLoadingBase.getInstance().getDumpSupplier().get(); + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaAPIWrapper.java b/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaAPIWrapper.java new file mode 100644 index 0000000..2a78b27 --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaAPIWrapper.java @@ -0,0 +1,37 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.platform.viaversion; + +import com.viaversion.viaversion.ViaAPIBase; +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import io.netty.buffer.ByteBuf; + +public class VLBViaAPIWrapper extends ViaAPIBase { + + @Override + public ProtocolVersion getPlayerProtocolVersion(UserConnection player) { + return player.getProtocolInfo().protocolVersion(); + } + + @Override + public void sendRawPacket(UserConnection player, ByteBuf packet) { + player.scheduleSendRawPacket(packet); + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaCommandHandler.java b/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaCommandHandler.java new file mode 100644 index 0000000..bbe8769 --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaCommandHandler.java @@ -0,0 +1,25 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.platform.viaversion; + +import com.viaversion.viaversion.commands.ViaCommandHandler; + +public class VLBViaCommandHandler extends ViaCommandHandler { + +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaConfig.java b/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaConfig.java new file mode 100644 index 0000000..7f8ac37 --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaConfig.java @@ -0,0 +1,53 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.platform.viaversion; + +import com.viaversion.viaversion.configuration.AbstractViaConfig; + +import java.io.File; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +public class VLBViaConfig extends AbstractViaConfig { + + // Stolen from Sponge + private final static List UNSUPPORTED = Arrays.asList("anti-xray-patch", "quick-move-action-fix", + "nms-player-ticking", "velocity-ping-interval", "velocity-ping-save", "velocity-servers", + "blockconnection-method", "change-1_9-hitbox", "change-1_14-hitbox", + "show-shield-when-sword-in-hand", "left-handed-handling"); + + + public VLBViaConfig(File configFile, Logger logger) { + super(configFile, logger); + + this.reload(); + } + + @Override + protected void handleConfig(Map config) { + // Nothing Currently + } + + @Override + public List getUnsupportedOptions() { + return UNSUPPORTED; + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaInjector.java b/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaInjector.java new file mode 100644 index 0000000..7154306 --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaInjector.java @@ -0,0 +1,65 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.platform.viaversion; + +import com.viaversion.viaversion.api.platform.ViaInjector; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import com.viaversion.viaversion.libs.fastutil.objects.ObjectLinkedOpenHashSet; +import com.viaversion.viaversion.libs.gson.JsonObject; +import de.florianmichael.vialoadingbase.netty.VLBPipeline; + +import java.util.SortedSet; + +public class VLBViaInjector implements ViaInjector { + + @Override + public void inject() { + } + + @Override + public void uninject() { + } + + @Override + public String getDecoderName() { + return VLBPipeline.VIA_DECODER_HANDLER_NAME; + } + + @Override + public String getEncoderName() { + return VLBPipeline.VIA_ENCODER_HANDLER_NAME; + } + + @Override + public SortedSet getServerProtocolVersions() { + final SortedSet versions = new ObjectLinkedOpenHashSet<>(); + versions.addAll(ProtocolVersion.getProtocols()); + return versions; + } + + @Override + public ProtocolVersion getServerProtocolVersion() { + return this.getServerProtocolVersions().first(); + } + + @Override + public JsonObject getDump() { + return new JsonObject(); + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaProviders.java b/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaProviders.java new file mode 100644 index 0000000..8371525 --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/platform/viaversion/VLBViaProviders.java @@ -0,0 +1,43 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.platform.viaversion; + +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.api.platform.ViaPlatformLoader; +import com.viaversion.viaversion.api.platform.providers.ViaProviders; +import com.viaversion.viaversion.api.protocol.version.VersionProvider; +import de.florianmichael.vialoadingbase.ViaLoadingBase; +import de.florianmichael.vialoadingbase.provider.VLBBaseVersionProvider; + +public class VLBViaProviders implements ViaPlatformLoader { + + @Override + public void load() { + // Now, we can implement custom providers + final ViaProviders providers = Via.getManager().getProviders(); + providers.use(VersionProvider.class, new VLBBaseVersionProvider()); + + if (ViaLoadingBase.getInstance().getProviders() != null) ViaLoadingBase.getInstance().getProviders().accept(providers); + } + + @Override + public void unload() { + // Nothing to do + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/provider/VLBBaseVersionProvider.java b/v1.20.2/src/florianmichael/vialoadingbase/provider/VLBBaseVersionProvider.java new file mode 100644 index 0000000..a16a6bf --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/provider/VLBBaseVersionProvider.java @@ -0,0 +1,35 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.provider; + +import com.viaversion.viaversion.api.connection.UserConnection; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import com.viaversion.viaversion.protocol.version.BaseVersionProvider; +import de.florianmichael.vialoadingbase.ViaLoadingBase; + +public class VLBBaseVersionProvider extends BaseVersionProvider { + + @Override + public ProtocolVersion getClosestServerProtocol(UserConnection connection) throws Exception { + if (connection.isClientSide()) { + return ViaLoadingBase.getInstance().getTargetVersion(); + } + return super.getClosestServerProtocol(connection); + } +} diff --git a/v1.20.2/src/florianmichael/vialoadingbase/util/JLoggerToLog4j.java b/v1.20.2/src/florianmichael/vialoadingbase/util/JLoggerToLog4j.java new file mode 100644 index 0000000..e6efd4d --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/util/JLoggerToLog4j.java @@ -0,0 +1,86 @@ +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.util; + +import java.text.MessageFormat; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +public class JLoggerToLog4j extends Logger { + private final org.apache.logging.log4j.Logger base; + + public JLoggerToLog4j(org.apache.logging.log4j.Logger logger) { + super("logger", null); + this.base = logger; + } + + public void log(LogRecord record) { + this.log(record.getLevel(), record.getMessage()); + } + + public void log(Level level, String msg) { + if (level == Level.FINE) { + this.base.debug(msg); + } else if (level == Level.WARNING) { + this.base.warn(msg); + } else if (level == Level.SEVERE) { + this.base.error(msg); + } else if (level == Level.INFO) { + this.base.info(msg); + } else { + this.base.trace(msg); + } + + } + + public void log(Level level, String msg, Object param1) { + if (level == Level.FINE) { + this.base.debug(msg, param1); + } else if (level == Level.WARNING) { + this.base.warn(msg, param1); + } else if (level == Level.SEVERE) { + this.base.error(msg, param1); + } else if (level == Level.INFO) { + this.base.info(msg, param1); + } else { + this.base.trace(msg, param1); + } + + } + + public void log(Level level, String msg, Object[] params) { + log(level, MessageFormat.format(msg, params)); + } + + public void log(Level level, String msg, Throwable params) { + if (level == Level.FINE) { + this.base.debug(msg, params); + } else if (level == Level.WARNING) { + this.base.warn(msg, params); + } else if (level == Level.SEVERE) { + this.base.error(msg, params); + } else if (level == Level.INFO) { + this.base.info(msg, params); + } else { + this.base.trace(msg, params); + } + + } +} \ No newline at end of file diff --git a/v1.20.2/src/florianmichael/vialoadingbase/util/VLBTask.java b/v1.20.2/src/florianmichael/vialoadingbase/util/VLBTask.java new file mode 100644 index 0000000..0ca2d3f --- /dev/null +++ b/v1.20.2/src/florianmichael/vialoadingbase/util/VLBTask.java @@ -0,0 +1,48 @@ + +/* + * This file is part of ViaLoadingBase - https://github.com/FlorianMichael/ViaLoadingBase + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.vialoadingbase.util; + +import com.viaversion.viaversion.api.platform.PlatformTask; +import com.viaversion.viaversion.api.scheduler.Task; +import com.viaversion.viaversion.api.scheduler.TaskStatus; + +public class VLBTask implements PlatformTask { + + private final Task object; + + public VLBTask(Task object) { + this.object = object; + } + + @Deprecated + public Task getObject() { + return object; + } + + @Override + public void cancel() { + object.cancel(); + } + + @Deprecated + public TaskStatus getStatus() { + return this.getObject().status(); + } +} \ No newline at end of file diff --git a/v1.20.2/src/florianmichael/viamcp/MCPVLBPipeline.java b/v1.20.2/src/florianmichael/viamcp/MCPVLBPipeline.java new file mode 100644 index 0000000..c67bfb2 --- /dev/null +++ b/v1.20.2/src/florianmichael/viamcp/MCPVLBPipeline.java @@ -0,0 +1,49 @@ +/* + * This file is part of ViaMCP - https://github.com/FlorianMichael/ViaMCP + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.viamcp; + +import com.viaversion.viaversion.api.connection.UserConnection; +import de.florianmichael.vialoadingbase.netty.VLBPipeline; + +public class MCPVLBPipeline extends VLBPipeline { + + public MCPVLBPipeline(UserConnection user) { + super(user); + } + + @Override + public String getDecoderHandlerName() { + return "decoder"; + } + + @Override + public String getEncoderHandlerName() { + return "encoder"; + } + + @Override + public String getDecompressionHandlerName() { + return "decompress"; + } + + @Override + public String getCompressionHandlerName() { + return "compress"; + } +} diff --git a/v1.20.2/src/florianmichael/viamcp/ViaMCP.java b/v1.20.2/src/florianmichael/viamcp/ViaMCP.java new file mode 100644 index 0000000..5733e13 --- /dev/null +++ b/v1.20.2/src/florianmichael/viamcp/ViaMCP.java @@ -0,0 +1,68 @@ +/* + * This file is part of ViaMCP - https://github.com/FlorianMichael/ViaMCP + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.viamcp; + +import com.viaversion.viabackwards.protocol.v1_17to1_16_4.Protocol1_17To1_16_4; +import com.viaversion.viaversion.api.Via; +import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ClientboundPackets1_16_2; +import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ServerboundPackets1_16_2; +import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ClientboundPackets1_17; +import com.viaversion.viaversion.protocols.v1_16_4to1_17.packet.ServerboundPackets1_17; +import de.florianmichael.vialoadingbase.ViaLoadingBase; + +import java.io.File; + +public class ViaMCP { + public final static int NATIVE_VERSION = 764; + public static ViaMCP INSTANCE; + + public static void create() { + INSTANCE = new ViaMCP(); + } + +// @Getter private AsyncVersionSlider asyncVersionSlider; + + public ViaMCP() { + ViaLoadingBase.ViaLoadingBaseBuilder.create().runDirectory(new File("ViaMCP")).nativeVersion(NATIVE_VERSION).onProtocolReload(protocolVersion -> { +// if (getAsyncVersionSlider() != null) { +// getAsyncVersionSlider().setVersion(protocolVersion.getVersion()); +// } + // TODO: SLider + }).build(); + + // Add this line if you implement the transaction fixes into the game code + // fixTransactions(); + } + + private void fixTransactions() { + // We handle the differences between those versions in the net code, so we can make the Via handlers pass through + final Protocol1_17To1_16_4 protocol = Via.getManager().getProtocolManager().getProtocol(Protocol1_17To1_16_4.class); + protocol.registerClientbound(ClientboundPackets1_17.PING, ClientboundPackets1_16_2.CONTAINER_ACK, wrapper -> {}, true); + protocol.registerServerbound(ServerboundPackets1_16_2.CONTAINER_ACK, ServerboundPackets1_17.PONG, wrapper -> {}, true); + } + + public void initAsyncSlider() { + this.initAsyncSlider(5, 5, 110, 20); + } + + public void initAsyncSlider(int x, int y, int width, int height) { +// asyncVersionSlider = new AsyncVersionSlider(-1, x, y, Math.max(width, 110), height); + } + +} diff --git a/v1.20.2/src/florianmichael/viamcp/fixes/AttackOrder.java b/v1.20.2/src/florianmichael/viamcp/fixes/AttackOrder.java new file mode 100644 index 0000000..fc256f9 --- /dev/null +++ b/v1.20.2/src/florianmichael/viamcp/fixes/AttackOrder.java @@ -0,0 +1,45 @@ +///* +// * This file is part of ViaMCP - https://github.com/FlorianMichael/ViaMCP +// * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.viamcp.fixes; +// +//import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +//import de.florianmichael.vialoadingbase.ViaLoadingBase; +//import de.florianmichael.viamcp.ViaMCP; +//import net.minecraft.client.Minecraft; +//import net.minecraft.entity.Entity; +//import net.minecraft.entity.player.EntityPlayer; +//import net.minecraft.util.MovingObjectPosition; +// +//public class AttackOrder { +// private final static Minecraft mc = Minecraft.getMinecraft(); +// +// public static void sendConditionalSwing(MovingObjectPosition mop) { +// if (mop != null && mop.typeOfHit != MovingObjectPosition.MovingObjectType.ENTITY) mc.thePlayer.swingItem(); +// } +// +// public static void sendFixedAttack(EntityPlayer entityIn, Entity target) { +// if (ViaLoadingBase.getInstance().getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) { +// mc.thePlayer.swingItem(); +// mc.playerController.attackEntity(entityIn, target); +// } else { +// mc.playerController.attackEntity(entityIn, target); +// mc.thePlayer.swingItem(); +// } +// } +//} diff --git a/v1.20.2/src/florianmichael/viamcp/fixes/FixedSoundEngine.java b/v1.20.2/src/florianmichael/viamcp/fixes/FixedSoundEngine.java new file mode 100644 index 0000000..cb6535f --- /dev/null +++ b/v1.20.2/src/florianmichael/viamcp/fixes/FixedSoundEngine.java @@ -0,0 +1,122 @@ +///* +// * This file is part of ViaMCP - https://github.com/FlorianMichael/ViaMCP +// * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.viamcp.fixes; +// +//import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +//import de.florianmichael.vialoadingbase.ViaLoadingBase; +//import de.florianmichael.viamcp.ViaMCP; +//import net.minecraft.block.Block; +//import net.minecraft.block.material.Material; +//import net.minecraft.block.state.IBlockState; +//import net.minecraft.client.Minecraft; +//import net.minecraft.entity.Entity; +//import net.minecraft.entity.player.EntityPlayer; +//import net.minecraft.init.Blocks; +//import net.minecraft.item.ItemBlock; +//import net.minecraft.item.ItemStack; +//import net.minecraft.util.BlockPos; +//import net.minecraft.util.EnumFacing; +//import net.minecraft.world.World; +// +//public class FixedSoundEngine { +// private final static Minecraft mc = Minecraft.getMinecraft(); +// +// /** +// * Fix for block breaking sounds on protocols above 1.8.x +// */ +// public static boolean destroyBlock(World world, BlockPos pos, boolean dropBlock) { +// IBlockState iblockstate = world.getBlockState(pos); +// Block block = iblockstate.getBlock(); +// +// // Moving playAusSFX out of else-statement to play sound correctly (For some reason block.getMaterial() always returns Material.air on 1.9+ protocols) +// // This should also function correctly on 1.8.x protocol, so no need for base version checks +// world.playAuxSFX(2001, pos, Block.getStateId(iblockstate)); +// +// if (block.getMaterial() == Material.air) +// { +// return false; +// } +// else +// { +// if (dropBlock) +// { +// block.dropBlockAsItem(world, pos, iblockstate, 0); +// } +// +// return world.setBlockState(pos, Blocks.air.getDefaultState(), 3); +// } +// } +// +// /** +// * Fix for block placing sounds on protocols above 1.8.x +// */ +// public static boolean onItemUse(ItemBlock iblock, ItemStack stack, EntityPlayer playerIn, World worldIn, BlockPos pos, EnumFacing side, float hitX, float hitY, float hitZ) +// { +// IBlockState iblockstate = worldIn.getBlockState(pos); +// Block block = iblockstate.getBlock(); +// +// if (!block.isReplaceable(worldIn, pos)) +// { +// pos = pos.offset(side); +// } +// +// if (stack.stackSize == 0) +// { +// return false; +// } +// else if (!playerIn.canPlayerEdit(pos, side, stack)) +// { +// return false; +// } +// else if (worldIn.canBlockBePlaced(iblock.getBlock(), pos, false, side, (Entity)null, stack)) +// { +// int i = iblock.getMetadata(stack.getMetadata()); +// IBlockState iblockstate1 = iblock.getBlock().onBlockPlaced(worldIn, pos, side, hitX, hitY, hitZ, i, playerIn); +// +// if (worldIn.setBlockState(pos, iblockstate1, 3)) +// { +// iblockstate1 = worldIn.getBlockState(pos); +// +// if (iblockstate1.getBlock() == iblock.getBlock()) +// { +// ItemBlock.setTileEntityNBT(worldIn, playerIn, pos, stack); +// iblock.getBlock().onBlockPlacedBy(worldIn, pos, iblockstate1, playerIn, stack); +// } +// +// if (ViaLoadingBase.getInstance().getTargetVersion().getOriginalVersion() != ViaMCP.NATIVE_VERSION) +// { +// // Using playSoundAtPos instead of playSoundEffect (I have no understanding as to why playSoundEffect is not functioning properly on 1.9+ protocols) +// mc.theWorld.playSoundAtPos(pos.add(0.5, 0.5, 0.5), iblock.getBlock().stepSound.getPlaceSound(), (iblock.getBlock().stepSound.getVolume() + 1.0F) / 2.0F, iblock.getBlock().stepSound.getFrequency() * 0.8F, false); +// } +// else +// { +// worldIn.playSoundEffect((double)((float)pos.getX() + 0.5F), (double)((float)pos.getY() + 0.5F), (double)((float)pos.getZ() + 0.5F), iblock.getBlock().stepSound.getPlaceSound(), (iblock.getBlock().stepSound.getVolume() + 1.0F) / 2.0F, iblock.getBlock().stepSound.getFrequency() * 0.8F); +// } +// +// --stack.stackSize; +// } +// +// return true; +// } +// else +// { +// return false; +// } +// } +//} diff --git a/v1.20.2/src/florianmichael/viamcp/gui/GuiProtocolSelector.java b/v1.20.2/src/florianmichael/viamcp/gui/GuiProtocolSelector.java new file mode 100644 index 0000000..8a4a247 --- /dev/null +++ b/v1.20.2/src/florianmichael/viamcp/gui/GuiProtocolSelector.java @@ -0,0 +1,289 @@ +/* + * This file is part of ViaMCP - https://github.com/FlorianMichael/ViaMCP + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.viamcp.gui; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.platform.InputConstants; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.*; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import de.florianmichael.vialoadingbase.ViaLoadingBase; +import de.florianmichael.viamcp.protocolinfo.ProtocolInfo; +import lombok.AllArgsConstructor; +import lombok.NonNull; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.ContainerObjectSelectionList; +import net.minecraft.client.gui.components.ObjectSelectionList; +import net.minecraft.client.gui.components.events.GuiEventListener; +import net.minecraft.client.gui.narration.NarratableEntry; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.gui.screens.worldselection.EditGameRulesScreen; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.FormattedCharSequence; +import net.minecraft.util.Mth; +import org.jetbrains.annotations.NotNull; +import org.lwjgl.opengl.GL11; +import slice.Slice; + +import javax.annotation.Nullable; +import java.io.IOException; +import java.util.List; + +public class GuiProtocolSelector extends Screen { + private final Screen parent; + private Button back; + public SlotList list; + + public GuiProtocolSelector(Screen parent) { + super(Component.text("ViaMCP Protocol Selector")); + + this.parent = parent; + } + + @Override + public void init() { + super.init(); + this.addRenderableWidget(this.back = Button.builder(Component.text("Back"), button -> { + assert this.minecraft != null; + this.minecraft.setScreen(parent); + }) + .bounds(width / 2 - 100, height - 25, 200, 20).build()); + list = new SlotList(Minecraft.getInstance(), width - 20, height, 57, height - 32, 20); + } + + @Override + public boolean mouseClicked(double p_94695_, double p_94696_, int p_94697_) { + if(back.isHovered()) { + return super.mouseClicked(p_94695_, p_94696_, p_94697_); + } + + list.mouseClicked(p_94695_, p_94696_, p_94697_); + return super.mouseClicked(p_94695_, p_94696_, p_94697_); + } + + @Override + public boolean mouseScrolled(double p_94686_, double p_94687_, double p_94688_, double p_299502_) { + if(back.isHovered()) { + return super.mouseScrolled(p_94686_, p_94687_, p_94688_, p_299502_); + } + + list.mouseScrolled(p_94686_, p_94687_, p_94688_, p_299502_); + return super.mouseScrolled(p_94686_, p_94687_, p_94688_, p_299502_); + } + + @Override + public boolean mouseReleased(double p_94722_, double p_94723_, int p_94724_) { + if(back.isHovered()) { + return super.mouseReleased(p_94722_, p_94723_, p_94724_); + } + + list.mouseReleased(p_94722_, p_94723_, p_94724_); + return super.mouseReleased(p_94722_, p_94723_, p_94724_); + } + + @Override + public boolean keyPressed(int p_96552_, int p_96553_, int p_96554_) { + long window = Minecraft.getInstance().getWindow().getWindow(); + + if(InputConstants.isKeyDown(window, InputConstants.KEY_UP)) { + list.setScrollAmount(list.getScrollAmount() - 20); + return true; + } else if(InputConstants.isKeyDown(window, InputConstants.KEY_DOWN)) { + list.setScrollAmount(list.getScrollAmount() + 20); + return true; + } else if(InputConstants.isKeyDown(window, InputConstants.KEY_TAB)) { + int index = ViaLoadingBase.PROTOCOLS.indexOf(ViaLoadingBase.getInstance().getTargetVersion()); + + if(InputConstants.isKeyDown(window, InputConstants.KEY_LSHIFT)) { + if(index <= 0) index = ViaLoadingBase.PROTOCOLS.size() - 1; + else index--; + } else { + if(index >= ViaLoadingBase.PROTOCOLS.size() - 1) index = 0; + else index++; + } + + final ProtocolVersion version = ViaLoadingBase.PROTOCOLS.get(index); + ViaLoadingBase.getInstance().reload(version); + + list.setScrollAmount(index * 20); + return true; + } + return super.keyPressed(p_96552_, p_96553_, p_96554_); + } + + @Override + public void render(@NotNull GuiGraphics graphics, int p_281550_, int p_282878_, float p_282465_) { + graphics.pose().pushPose(); + graphics.pose().scale(2.0F, 2.0F, 2.0F); + + String title = "§lViaMCP"; + Font font = Minecraft.getInstance().font; + + graphics.drawString(font, title, (this.width - (font.width(title) * 2)) / 4, 5, -1); + graphics.pose().popPose(); + + graphics.drawString(font, "by EnZaXD/Flori2007", 1, 1, -1); + graphics.drawString(font, "Discord: @florianmichael", 1, 11, -1); + + graphics.drawString(font, "Updated by NickRest", 1, 21, -1); + graphics.drawString(font, "Discord: @nickrest", 1, 31, -1); + + final ProtocolInfo protocolInfo = ProtocolInfo.fromProtocolVersion(ViaLoadingBase.getInstance().getTargetVersion()); + + final String versionTitle = "Version: " + ViaLoadingBase.getInstance().getTargetVersion().getName() + " - " + protocolInfo.getName(); + final String versionReleased = "Released: " + protocolInfo.getReleaseDate(); + + final int fixedHeight = ((5 + font.lineHeight) * 2) + 2; + + graphics.drawString(font, "§7§lVersion Information", (width - font.width("Version Information")) / 2, fixedHeight, -1); + graphics.drawString(font, versionTitle, (width - font.width(versionTitle)) / 2, fixedHeight + font.lineHeight, -1); + graphics.drawString(font, versionReleased, (width - font.width(versionReleased)) / 2, fixedHeight + font.lineHeight * 2, -1); + + list.render(graphics, p_281550_, p_282878_, p_282465_); + super.render(graphics, p_281550_, p_282878_, p_282465_); + } + + abstract static class VersionEntry extends ContainerObjectSelectionList.Entry{}; + + static class SlotList extends ContainerObjectSelectionList { + + public SlotList(Minecraft p_94010_, int p_94011_, int p_94012_, int p_94013_, int p_94014_, int p_94015_) { + super(p_94010_, p_94011_, p_94012_, p_94013_, p_94014_, p_94015_); + } + + @Override + protected int getItemCount() { + return ViaLoadingBase.PROTOCOLS.size(); + } + + @Override + public boolean isFocused() { + return false; + } + + @Override + public void setRenderBackground(boolean p_93489_) { + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + this.minecraft.getTextureManager().bindForSetup(EditGameRulesScreen.BACKGROUND_LOCATION); + blit(0, 0, 0, 0, this.width, this.height); + } + + @Override + public void render(GuiGraphics p_282708_, int p_283242_, int p_282891_, float p_283683_) { + if (this.renderBackground) { + p_282708_.setColor(0.125F, 0.125F, 0.125F, 1.0F); + int i = 32; + p_282708_.blit(Screen.BACKGROUND_LOCATION, this.x0, this.y0, (float)this.x1, (float)(this.y1 + (int)this.getScrollAmount()), this.x1 - this.x0, this.y1 - this.y0, 32, 32); + p_282708_.setColor(1.0F, 1.0F, 1.0F, 1.0F); + } + + this.enableScissor(p_282708_); + if (this.renderHeader) { + int i1 = this.getRowLeft(); + int j = this.y0 + 4 - (int)this.getScrollAmount(); + this.renderHeader(p_282708_, i1, j); + } + + this.renderList(p_282708_, p_283242_, p_282891_, p_283683_); + p_282708_.disableScissor(); + if (this.renderBackground) { + int j1 = 4; + p_282708_.fillGradient(RenderType.guiOverlay(), this.x0, this.y0, this.x1, this.y0 + 4, -16777216, 0, 0); + p_282708_.fillGradient(RenderType.guiOverlay(), this.x0, this.y1 - 4, this.x1, this.y1, 0, -16777216, 0); + } + + int k1 = this.getMaxScroll(); + if (k1 > 0) { + int l1 = this.getScrollbarPosition(); + int k = (int)((float)((this.y1 - this.y0) * (this.y1 - this.y0)) / (float)this.getMaxPosition()); + k = Mth.clamp(k, 32, this.y1 - this.y0 - 8); + int l = (int)this.getScrollAmount() * (this.y1 - this.y0 - k) / k1 + this.y0; + if (l < this.y0) { + l = this.y0; + } + + p_282708_.fill(l1, this.y0, l1 + 6, this.y1, -16777216); + p_282708_.blitSprite(new ResourceLocation("widget/scroller"), l1, l, 6, k); + } + + this.renderDecorations(p_282708_, p_283242_, p_282891_); + RenderSystem.disableBlend(); + } + + @Override + protected void renderItem(@NotNull GuiGraphics graphics, int p_238966_, int p_238967_, float p_238968_, int idkWhatThisIs, int p_238970_, int p_238971_, int p_238972_, int p_238973_) { + + Font font = Minecraft.getInstance().font; + try { + graphics.drawString(font, (ViaLoadingBase.PROTOCOLS.indexOf(ViaLoadingBase.getInstance().getTargetVersion()) == idkWhatThisIs ? "§a§l" : "§7") + ViaLoadingBase.PROTOCOLS.get(idkWhatThisIs).getName(), width / 2, p_238971_ + 2, -1); + + PoseStack poseStack = graphics.pose(); + poseStack.pushPose(); + poseStack.scale(0.5F, 0.5F, 0.5F); + graphics.drawString(font, "PVN: " + ViaLoadingBase.PROTOCOLS.get(idkWhatThisIs).getVersion(), width, (p_238971_ + 2) * 2 + 20, -1); + poseStack.popPose(); + } catch (Exception e) { + e.printStackTrace(); // don't crash just tell me please + } + } + + @Override + public boolean mouseClicked(double p_93420_, double p_93421_, int p_93422_) { + final ProtocolVersion version = getVersionFromFound(p_93420_, p_93421_); + ViaLoadingBase.getInstance().reload(version); + + return false; // if I return super it crashses + } + + public ProtocolVersion getVersionFromFound(double x, double y) { + int scroll = (int) getScrollAmount(); + + for (int i = 0; i < getItemCount(); i++) { + int y1 = y0 + 4 + (i * 20) - scroll; + int y2 = y0 + 4 + (i * 20) + 20 - scroll; + + if (y >= y1 && y <= y2) { + return ViaLoadingBase.PROTOCOLS.get(i); + } + } + + return null; + } + + public void blit(int p_94017_, int p_94018_, int p_94019_, int p_94020_, int p_94021_, int p_94022_) { + float f = 0.00390625F; + float f1 = 0.00390625F; + BufferBuilder bufferbuilder = Tesselator.getInstance().getBuilder(); + bufferbuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX); + bufferbuilder.vertex(p_94017_, p_94018_ + p_94022_, 0.0D).uv(p_94019_ * f, (p_94020_ + p_94022_) * f1).endVertex(); + bufferbuilder.vertex(p_94017_ + p_94021_, p_94018_ + p_94022_, 0.0D).uv((p_94019_ + p_94021_) * f, (p_94020_ + p_94022_) * f1).endVertex(); + bufferbuilder.vertex(p_94017_ + p_94021_, p_94018_, 0.0D).uv((p_94019_ + p_94021_) * f, p_94020_ * f1).endVertex(); + bufferbuilder.vertex(p_94017_, p_94018_, 0.0D).uv(p_94019_ * f, p_94020_ * f1).endVertex(); + bufferbuilder.end(); + BufferUploader.reset(); + } + } + + +} diff --git a/v1.20.2/src/florianmichael/viamcp/protocolinfo/ProtocolInfo.java b/v1.20.2/src/florianmichael/viamcp/protocolinfo/ProtocolInfo.java new file mode 100644 index 0000000..50514b3 --- /dev/null +++ b/v1.20.2/src/florianmichael/viamcp/protocolinfo/ProtocolInfo.java @@ -0,0 +1,111 @@ +/* + * This file is part of ViaMCP - https://github.com/FlorianMichael/ViaMCP + * Copyright (C) 2020-2024 FlorianMichael/EnZaXD 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.viamcp.protocolinfo; + +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; + +import java.util.Arrays; +import java.util.List; + +public class ProtocolInfo { + private static final String NO_DESC = "No Description Available"; + + public static ProtocolInfo R1_21 = new ProtocolInfo("Tricky Trials", NO_DESC, "June 13, 2024", ProtocolVersion.v1_21); + public static ProtocolInfo R1_20_5 = new ProtocolInfo("Trails & Tales", NO_DESC, "April 23, 2024", ProtocolVersion.v1_20_5); + public static ProtocolInfo R1_20_3 = new ProtocolInfo("Trails & Tales", NO_DESC, "December 5, 2023", ProtocolVersion.v1_20_3); + public static ProtocolInfo R1_20_2 = new ProtocolInfo("Trails & Tales", NO_DESC, "September 21, 2023", ProtocolVersion.v1_20_2); + public static ProtocolInfo R1_20 = new ProtocolInfo("Trails & Tales", NO_DESC, "16 May, 2023", ProtocolVersion.v1_20); + public static ProtocolInfo R1_19_4 = new ProtocolInfo("The Wild Update", NO_DESC, "14 March, 2022", ProtocolVersion.v1_19_4); + public static ProtocolInfo R1_19_3 = new ProtocolInfo("The Wild Update", NO_DESC, "August 5, 2022 - December 17, 2022", ProtocolVersion.v1_19_3); + public static ProtocolInfo R1_19_1 = new ProtocolInfo("The Wild Update", NO_DESC, "July 27, 2022 - August 5, 2022", ProtocolVersion.v1_19_1); + public static ProtocolInfo R1_19 = new ProtocolInfo("The Wild Update", NO_DESC, "June 7, 2022", ProtocolVersion.v1_19); + public static ProtocolInfo R1_18_2 = new ProtocolInfo("Caves & Cliffs: Part II", NO_DESC, "February 28, 2022", ProtocolVersion.v1_18_2); + public static ProtocolInfo R1_18 = new ProtocolInfo("Caves & Cliffs: Part II", NO_DESC, "November 30, 2021 - December 10, 2021", ProtocolVersion.v1_18); + public static ProtocolInfo R1_17_1 = new ProtocolInfo("Caves & Cliffs: Part I", NO_DESC, "July 6, 2021", ProtocolVersion.v1_17_1); + public static ProtocolInfo R1_17 = new ProtocolInfo("Caves & Cliffs: Part I", NO_DESC, "June 8, 2021", ProtocolVersion.v1_17); + public static ProtocolInfo R1_16_4 = new ProtocolInfo("Nether Update", NO_DESC, "November 2, 2020 - January 13, 2021", ProtocolVersion.v1_16_4); + public static ProtocolInfo R1_16_3 = new ProtocolInfo("Nether Update", NO_DESC, "September 7, 2020", ProtocolVersion.v1_16_3); + public static ProtocolInfo R1_16_2 = new ProtocolInfo("Nether Update", NO_DESC, "August 11, 2020", ProtocolVersion.v1_16_2); + public static ProtocolInfo R1_16_1 = new ProtocolInfo("Nether Update", NO_DESC, "June 24, 2020", ProtocolVersion.v1_16_1); + public static ProtocolInfo R1_16 = new ProtocolInfo("Nether Update", NO_DESC, "June 23, 2020", ProtocolVersion.v1_16); + public static ProtocolInfo R1_15_2 = new ProtocolInfo("Buzzy Bees", NO_DESC, "January 21, 2020", ProtocolVersion.v1_15_2); + public static ProtocolInfo R1_15_1 = new ProtocolInfo("Buzzy Bees", NO_DESC, "December 17, 2019", ProtocolVersion.v1_15_1); + public static ProtocolInfo R1_15 = new ProtocolInfo("Buzzy Bees", NO_DESC, "December 10, 2019", ProtocolVersion.v1_15); + public static ProtocolInfo R1_14_4 = new ProtocolInfo("Village & Pillage", NO_DESC, "July 19, 2019", ProtocolVersion.v1_14_4); + public static ProtocolInfo R1_14_3 = new ProtocolInfo("Village & Pillage", NO_DESC, "June 24, 2019", ProtocolVersion.v1_14_3); + public static ProtocolInfo R1_14_2 = new ProtocolInfo("Village & Pillage", NO_DESC, "May 27, 2019", ProtocolVersion.v1_14_2); + public static ProtocolInfo R1_14_1 = new ProtocolInfo("Village & Pillage", NO_DESC, "May 13, 2019", ProtocolVersion.v1_14_1); + public static ProtocolInfo R1_14 = new ProtocolInfo("Village & Pillage", NO_DESC, "April 23, 2019", ProtocolVersion.v1_14); + public static ProtocolInfo R1_13_2 = new ProtocolInfo("Update Aquatic", NO_DESC, "October 22, 2018", ProtocolVersion.v1_13_2); + public static ProtocolInfo R1_13_1 = new ProtocolInfo("Update Aquatic", NO_DESC, "August 22, 2018", ProtocolVersion.v1_13_1); + public static ProtocolInfo R1_13 = new ProtocolInfo("Update Aquatic", NO_DESC, "July 18, 2018", ProtocolVersion.v1_13); + public static ProtocolInfo R1_12_2 = new ProtocolInfo("World of Color Update", NO_DESC, "September 18, 2017", ProtocolVersion.v1_12_2); + public static ProtocolInfo R1_12_1 = new ProtocolInfo("World of Color Update", NO_DESC, "August 3, 2017", ProtocolVersion.v1_12_1); + public static ProtocolInfo R1_12 = new ProtocolInfo("World of Color Update", NO_DESC, "June 7, 2017", ProtocolVersion.v1_12); + public static ProtocolInfo R1_11_1 = new ProtocolInfo("Exploration Update", NO_DESC, "December 20, 2016 - December 21, 2016", ProtocolVersion.v1_11_1); + public static ProtocolInfo R1_11 = new ProtocolInfo("Exploration Update", NO_DESC, "November 14, 2016", ProtocolVersion.v1_11); + public static ProtocolInfo R1_10 = new ProtocolInfo("Frostburn Update", NO_DESC, "June 8, 2016 - June 23, 2016", ProtocolVersion.v1_10); + public static ProtocolInfo R1_9_3 = new ProtocolInfo("Combat Update", NO_DESC, "May 10, 2016", ProtocolVersion.v1_9_3); + public static ProtocolInfo R1_9_2 = new ProtocolInfo("Combat Update", NO_DESC, "March 30, 2016", ProtocolVersion.v1_9_2); + public static ProtocolInfo R1_9_1 = new ProtocolInfo("Combat Update", NO_DESC, "March 30, 2016", ProtocolVersion.v1_9_1); + public static ProtocolInfo R1_9 = new ProtocolInfo("Combat Update", NO_DESC, "February 29, 2016", ProtocolVersion.v1_9); + public static ProtocolInfo R1_8 = new ProtocolInfo("Bountiful Update", NO_DESC, "September 2, 2014 - December 9, 2015", ProtocolVersion.v1_8); + public static ProtocolInfo R1_7_6 = new ProtocolInfo("The Update that Changed the World", NO_DESC, "April 9, 2014 - June 26, 2014", ProtocolVersion.v1_7_6); + public static ProtocolInfo R1_7 = new ProtocolInfo("The Update that Changed the World", NO_DESC, "October 22, 2013 - February 26, 2014", ProtocolVersion.v1_7_2); + + private final static List PROTOCOL_INFOS = Arrays.asList(R1_7, R1_7_6, R1_8, R1_9, R1_9_1, R1_9_2, R1_9_3, R1_10, R1_11, R1_11_1, R1_12, R1_12_1, R1_12_2, R1_13, R1_13_1, R1_13_2, R1_14, R1_14_1, R1_14_2, R1_14_3, R1_14_4, + R1_15, R1_15_1, R1_15_2, R1_16, R1_16_1, R1_16_2, R1_16_3, R1_16_4, R1_17, R1_17_1, R1_18, R1_18_2, R1_19, R1_19_1, R1_19_3, R1_19_4, R1_20, R1_20_2, R1_20_3, R1_20_5, R1_21); + + private final String name; + private final String description; + private final String releaseDate; + private final ProtocolVersion protocolVersion; + + public ProtocolInfo(final String name, final String description, final String releaseDate, final ProtocolVersion protocolVersion) { + this.name = name; + this.description = description; + this.releaseDate = releaseDate; + this.protocolVersion = protocolVersion; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public String getReleaseDate() { + return releaseDate; + } + + public ProtocolVersion getProtocolVersion() { + return protocolVersion; + } + + public static ProtocolInfo fromProtocolVersion(final ProtocolVersion protocolVersion) { + for (ProtocolInfo protocolInfo : PROTOCOL_INFOS) { + if (protocolInfo.getProtocolVersion().getName().equals(protocolVersion.getName())) { + return protocolInfo; + } + } + return null; + } +} diff --git a/v1.8.x/README.md b/v1.8.x/README.md new file mode 100644 index 0000000..f4ed8ff --- /dev/null +++ b/v1.8.x/README.md @@ -0,0 +1,268 @@ +# ViaMCP +ViaVersion VersionSwitcher for Minecraft Coder Pack (MCP) + + +* [ViaMCP](#viamcp) + * [Contact](#contact) + * [Setup](#setup) + * [Main-Class](#main-class) + * [NetworkManager](#networkmanager) + * [Version Control](#version-control) + * [Version Slider](#version-slider) + * [Clientside Fixes](#clientside-fixes) + * [Attack Order Fixes](#attack-order-fixes) + * [Block Sound Fixes](#block-sound-fixes) + * [Transaction Fixes for 1.17+](#transaction-fixes-for-117) + * [Exporting Without JAR Files](#exporting-without-jar-files) + +## Contact +If you encounter any issues, please report them on the +[issue tracker](https://github.com/FlorianMichael/ViaMCP/issues). +If you just want to talk or need help with ViaMCP feel free to join my +[Discord](https://discord.gg/BwWhCHUKDf). + +# Updating notice for existing users (if you are new to ViaMCP, you can ignore this) +ViaVersion 4.10.0 did some changes to the ProtocolVersion API, you have to update your own code if you ever used the ViaLoadingBase class: +```java +// 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()); +``` +In addition to that, the *ComparableProtocolVersion* class has been removed and it's methods have been moved to the *ProtocolVersion* class. + +## Setup +Firstly, you will need to add the listed libraries into your dependencies in IntelliJ or Eclipse + +Dependencies (Included inside ``libraries`` folder) +``` +downgraded-ViaVersion-[ver].jar > ViaVersion > https://github.com/ViaVersion/ViaVersion +downgraded-ViaBackwards-[ver].jar > ViaBackwards > https://github.com/ViaVersion/ViaBackwards +downgraded-ViaRewind-[ver].jar > ViaRewind > https://github.com/ViaVersion/ViaRewind +snakeyml-2.2.jar > SnakeYaml > https://bitbucket.org/snakeyaml/snakeyaml +``` + +Secondly, you need to add code that allows you to actually use ViaMCP (**Choose the version folder that corresponds with your client version**) + +For 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 +other major versions [here](https://github.com/ViaVersion/ViaForge) + +NOTE: +ViaVersion 5.0.0+ doesn't support Java 8 anymore, therefore when updating the libraries yourself, you need to download +the -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. + +### Main-Class +Add this to the main class of your client (aka injection function) + +```java +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 +You will need to modify 2 methods inside NetworkManager.java + +**1. Hook ViaVersion into the Netty Pipeline** + +Find the method, that is ``func_181124_a``, ``createNetworkManagerAndConnect`` or contains ``(Bootstrap)((Bootstrap)((Bootstrap)(new Bootstrap()).group((EventLoopGroup)lazyloadbase.getValue())`` + +Find the vanilla network pipeline call: +```java +// 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); +``` + +After the vanilla network pipeline call, add the ViaMCP protocol pipeline hook: +```java +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)); +} +``` + +Your 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: +```java +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)); +} +``` + +### 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! + +**2. Fix the compression in the NetworkManager#setCompressionTreshold function** + +Simply call the following code at the end of the method in Minecraft: +```java +this.channel.pipeline().fireUserEventTriggered(new CompressionReorderEvent()); +``` + +## Version Control +You will need to add a button to access the protocol switcher (or alternatively use the version slider under this section)
+In ``addSingleplayerMultiplayerButtons()`` function add (if in GuiMainMenu): +```java +this.buttonList.add(new GuiButton(69, 5, 5, 90, 20, "Version")); +``` +In ``actionPerformed()`` function add: +```java +if (button.id == 69) +{ + this.mc.displayGuiScreen(new GuiProtocolSelector(this)); +} +``` +### Version Slider +You can also use a version slider to control ViaMCP versions +```java +this.buttonList.add(ViaMCP.INSTANCE.getAsyncVersionSlider()); +``` + +## Clientside Fixes +### Attack Order Fixes +**Class: Minecraft.java**
+**Function: clickMouse()**
+ +**1.8.x**
+Replace ``this.thePlayer.swingItem();`` on the 1st line in the if-clause with: +```java +AttackOrder.sendConditionalSwing(this.objectMouseOver); +``` +Replace ``this.playerController.attackEntity(this.thePlayer, this.objectMouseOver.entityHit);`` in the switch in case ``ENTITY`` with: +```java +AttackOrder.sendFixedAttack(this.thePlayer, this.objectMouseOver.entityHit); +``` + +**1.12.2**
+Replace ``this.player.swingArm(EnumHand.MAIN_HAND);`` at the last line in the else if-clause with: +```java +AttackOrder.sendConditionalSwing(this.objectMouseOver, EnumHand.MAIN_HAND); +``` +Replace ``this.playerController.attackEntity(this.player, this.objectMouseOver.entityHit);`` in the switch in case ``ENTITY`` with: +```java +AttackOrder.sendFixedAttack(this.thePlayer, this.objectMouseOver.entityHit, EnumHand.MAIN_HAND); +``` + +### Block Sound Fixes +**Block Placement** + +Replace all code in ``onItemUse`` function in the ``ItemBlock`` class with: +```java +return FixedSoundEngine.onItemUse(this, stack, playerIn, worldIn, pos, side, hitX, hitY, hitZ); +``` + +**Block Breaking** + +Replace all code in ``destroyBlock`` function in the ``World`` class with: +```java +return FixedSoundEngine.destroyBlock(this, pos, dropBlock); +``` + +### Transaction Fixes for 1.17+ +Call the ``fixTransactions();`` in the ``ViaMCP`` class file so ViaVersion doesn't remap anything in transaction packets. + +After that, you need to do some changes in the Game code: + +**Class: S32PacketConfirmTransaction.java**
+**Function: readPacketData()**
+ +Replace the code with this method: +```java +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(); + } +} +``` + +**Class: C0FPacketConfirmTransaction.java**
+**Function: writePacketData()**
+ +Replace the code with this method: +```java +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); + } +} +``` + +Note: this code can be different depending on your mappings and game version, you just need to make sure +it only reads the window id and doesn't read the rest of the packet because we previously removed the +ViaVersion handlers which would have handled the rest of the packet. + +**Class: NetHandlerPlayClient.java**
+**Function: handleConfirmTransaction()**
+ +Add this code after the checkThreadAndEnqueue function call: +```java +if (ViaLoadingBase.getInstance().getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_17)) { + this.addToSendQueue(new C0FPacketConfirmTransaction(packetIn.getWindowId(), 0, false)); + return; +} +``` + +## Sending raw packets (e.g 1.9 interactions) +You can send raw packets with ViaMCP, you can use the following code to send raw packets: +```java +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); +} +``` + +## Exporting Without JAR Files +This should fix most peoples issues with dependencies (usually NoClassDefFoundError or ClassNotFoundException) + +- First export your client normally +- Open your client .jar file with an archive program (winrar or 7zip for example) +- Also open all libraries with the selected archive program (ViaVersion, ViaBackwards, ViaRewind and SnakeYaml) +- From ViaBackwards drag and drop ``assets`` and ``com`` folders to your client .jar +- From ViaRewind drag and drop ``assets`` and ``de`` folders to your client .jar +- From ViaSnakeYaml drag and drop ``org`` folder to your client .jar +- From ViaVersion drag and drop ``assets``, ``com`` and ``us`` folders to your client .jar +- Then save and close, now your client should be working correctly ;) \ No newline at end of file