Compare commits

..

No commits in common. "main" and "v3.1.1" have entirely different histories.
main ... v3.1.1

273 changed files with 4394 additions and 13222 deletions

View File

@ -1,10 +0,0 @@
version: 2
updates:
- package-ecosystem: "gradle"
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

View File

@ -1,19 +1,19 @@
name: Build
name: ViaFabricPlus CI
on: [pull_request, push, workflow_dispatch]
jobs:
build:
runs-on: ubuntu-24.04
runs-on: ubuntu-22.04
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v4
- name: Set up JDK 21
uses: gradle/actions/wrapper-validation@v3
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 21
java-version: 17
check-latest: true
- name: Build with Gradle
run: ./gradlew build
@ -21,4 +21,4 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: Artifacts
path: build/libs/
path: build/libs/

View File

@ -1,20 +0,0 @@
name: Update Gradle Wrapper
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * 0"
jobs:
update-gradle-wrapper:
runs-on: ubuntu-24.04
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 21
check-latest: true
- name: Update Gradle Wrapper
uses: gradle-update/update-gradle-wrapper-action@v2

View File

@ -1,45 +0,0 @@
# Contributing guidelines for the project
## Setting up a Workspace
ViaFabricPlus uses Gradle, to make sure that it is installed properly you can check [Gradle's website](https://gradle.org/install/).
1. Clone the repository using `git clone https://github.com/ViaVersion/ViaFabricPlus`.
2. CD into the local repository.
3. Run `./gradlew genSources`.
4. Open the folder as a Gradle project in your preferred IDE.
5. Run the mod.
## Update translation files
Translation files are located in `src/main/resources/assets/viafabricplus/lang/`. To update them, you need to do the following:
1. Copy the `en_us.json` file and rename it to the language code of the language you want to update (e.g. `de_de.json` for German)
2. Translate all values in the file to the language you want to update
3. Do not change the keys of the values, only the values themselves
4. Do not change the formatting of the file (e.g. the spaces between the keys and values or the order of the keys)
5. Try to be consistent with Minecraft language files.
6. Take a look at UN's guidelines for Gender-inclusive language: https://www.un.org/en/gender-inclusive-language/guidelines.shtml
7. Create a pull request and wait for it to be reviewed and merged.
8. You're done, congrats!
## Add a new feature or fix a bug
1. Create a new branch for your feature/bugfix (e.g. `feature/fix-xyz` or `fix/fix-xyz`)
2. Implement your feature/bugfix and make sure it works correctly
3. Clean your code and make sure it is readable and understandable (e.g. use proper variable names)
4. Use the Google java code style (https://google.github.io/styleguide/javaguide.html) and format your code accordingly
5. If you're changing API, make sure to update the documentation in the `docs` folder, add javadocs to your code and don't break backwards compatibility if not necessary
6. Create a pull request and wait for it to be reviewed and merged.
7. You're done, congrats!
## Adding protocol new fixes - which are important and which aren't?
Protocol fixes are the core functionality of ViaFabricPlus, they make ViaFabricPlus stand out from all other existing
protocol translation platforms, and so it's even more important to keep them working.
When adding new fixes, you should always check if the fix is relevant for the current version of the game. If you're unsure,
ask in the ViaVersion discord.
In general, you should only implement changes which could be detected by the server or are relevant for the gameplay.
From experience, most changes are related to either movement or networking. If you contribute new fixes, please proof
your changes by showing that they are relevant and also by providing a game source diff. **It's important that fixes
are changing the actual change happend in the game and not just visual changes.**
## Maintaining the mod
See [MAINTAINING.md](docs/MAINTAINING.md) for more information on how to maintain the mod.

View File

@ -12,46 +12,30 @@
</div>
# Why another protocol translator?
ViaFabricPlus implements the [ViaVersion projects](https://github.com/ViaVersion) into Fabric and provides tons of fixes to the existing protocol translation which can't be implemented in the original ViaVersion project.
These fixes consist of movement changes, block/entity collisions, rendering changes, and many more.
At the time of writing, ViaFabricPlus is the only mod that supports joining all Minecraft server versions down to the first multiplayer version while implementing
legacy combat mechanics, movement, and rendering changes to make the gameplay feel more like the old days.
**On the other hand, ViaFabricPlus supports only the latest Minecraft client version, and only Fabric.**
If you need ViaFabricPlus for older versions of the game, you can use [ViaFabric](https://viaversion.com/fabric)
ViaFabricPlus is a deep integration of ViaVersion on the Fabric platform, it implements many changes that can't be fixed on protocol level (old animations, old movement/swimming, collisions and general rendering changes).
At the time of writing, VFP is the only protocol translation platform for the client with which you can play on all Minecraft multiplayer versions with many QoL features and get the feel of the old versions.
## Supported Server versions
- Release (1.0.0 - 1.21.1)
- Release (1.0.0 - 1.20.5)
- Beta (b1.0 - b1.8.1)
- Alpha (a1.0.15 - a1.2.6)
- Classic (c0.0.15 - c0.30 including [CPE](https://wiki.vg/Classic_Protocol_Extension))
- April Fools (3D Shareware, 20w14infinite)
- Combat Snapshots (Combat Test 8c)
- Bedrock Edition 1.21.30 ([Some features are missing](https://github.com/RaphiMC/ViaBedrock#features))
- Bedrock Edition 1.20.70 ([Some features are missing](https://github.com/RaphiMC/ViaBedrock#features))
## How to (Users)
- [A detailed guide on how to install and use the mod](docs/USAGE.md)
- If you encounter any issues, please report them on either:
- [the issue tracker](https://github.com/ViaVersion/ViaFabricPlus/issues)
- [the ViaVersion Discord](https://discord.gg/viaversion)
## For players
- Tutorial for installing and using the mod can be found [here](docs/USAGE.md)
- If you encounter any issues, please report them on the [issue tracker](https://github.com/ViaVersion/ViaFabricPlus/issues) or on the ViaVersion [Discord](https://discord.gg/viaversion)
## How to (Developers)
- [Detailed guidelines for contributions as well as setting up a dev environment](CONTRIBUTING.md)
- [API and integration examples for developers](docs/DEVELOPER_API.md)
## For contributors/volunteers
- Guidelines for contributions can be found [here](docs/UPDATE_INSTRUCTIONS.md)
- The current TODO list can be found [here](https://github.com/ViaVersion/ViaFabricPlus/blob/main/src/main/java/de/florianmichael/viafabricplus/ViaFabricPlus.java)
## ViaFabric
[ViaFabric](https://github.com/ViaVersion/ViaFabric) can be used for server-side purposes or when using older versions of the game.
### Does it work with ViaFabricPlus:
- No, ViaFabricPlus cannot be used with ViaFabric.
### Differences with ViaFabric:
https://github.com/ViaVersion/ViaFabric?tab=readme-ov-file#differences-with-viafabricplus
## Credits
Special thanks to all our [Contributors](https://github.com/ViaVersion/ViaFabricPllus/graphs/contributors).
## Miscellaneous
- API and integration examples can be found [here](docs/DEVELOPER_API.md)
- An overview of the different Via* projects can be found [here](https://github.com/ViaVersion)
#### If you just want to talk or need help with ViaFabricPlus feel free to join my [Discord](https://discord.gg/BwWhCHUKDf).
## Disclaimer
It cannot be guaranteed that this mod is allowed on specific servers as it can possibly cause problems with anti-cheat plugins.\

View File

@ -1,13 +1,12 @@
plugins {
id "fabric-loom" version "1.7-SNAPSHOT"
id "fabric-loom" version "1.6-SNAPSHOT"
id "maven-publish"
}
base {
archivesName = project.archives_base_name
version = project.mod_version
group = project.maven_group
archivesName = project.maven_name
version = project.maven_version
description = project.maven_description
}
configurations {
@ -21,6 +20,10 @@ configurations {
repositories {
mavenCentral()
maven {
name = "Jitpack"
url = "https://jitpack.io"
}
maven {
name = "ViaVersion"
url = "https://repo.viaversion.com"
@ -29,21 +32,13 @@ repositories {
name = "Lenni0451"
url = "https://maven.lenni0451.net/everything"
}
maven {
name = "OpenCollab Snapshots"
url = "https://repo.opencollab.dev/maven-snapshots/"
}
maven {
name = "TerraformersMC"
url = "https://maven.terraformersmc.com/releases"
}
maven {
name = "Jitpack"
url = "https://jitpack.io"
content {
includeGroup "com.github.Oryxel"
}
name = "OpenCollab Snapshots"
url = "https://repo.opencollab.dev/maven-snapshots/"
}
}
@ -52,10 +47,14 @@ loom {
}
dependencies {
// Minecraft/Fabric and mods
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_version}:v2"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modCompileOnly "com.terraformersmc:modmenu:${project.mod_menu_version}"
// Fabric API
modJij(fabricApi.module("fabric-api-base", project.fabric_api_version))
modJij(fabricApi.module("fabric-resource-loader-v0", project.fabric_api_version))
modJij(fabricApi.module("fabric-networking-api-v1", project.fabric_api_version))
@ -64,41 +63,43 @@ dependencies {
modJij(fabricApi.module("fabric-particles-v1", project.fabric_api_version))
modJij(fabricApi.module("fabric-registry-sync-v0", project.fabric_api_version))
modCompileOnly "com.terraformersmc:modmenu:11.0.2"
jij "com.viaversion:viaversion-common:5.0.4-SNAPSHOT"
jij "com.viaversion:viabackwards-common:5.0.4-SNAPSHOT"
jij "net.raphimc:viaaprilfools-common:3.0.2-SNAPSHOT"
jij "net.raphimc:ViaLegacy:3.0.3-SNAPSHOT"
jij ("net.raphimc:ViaBedrock:0.0.12-SNAPSHOT") {
// ViaVersion Libraries
jij "com.viaversion:viaversion-common:${project.viaversion_version}"
jij "com.viaversion:viabackwards-common:${project.viabackwards_version}"
jij "net.raphimc:ViaLegacy:${project.vialegacy_version}"
jij "net.raphimc:ViaAprilFools:${project.viaaprilfools_version}"
jij ("net.raphimc:ViaBedrock:${project.viabedrock_version}") {
exclude group: "io.netty"
exclude group: "io.jsonwebtoken"
exclude group: "com.mojang", module: "brigadier"
}
jij ("net.raphimc:ViaLoader:3.0.3-SNAPSHOT") {
jij ("net.raphimc:ViaLoader:${project.vialoader_version}") {
exclude group: "com.google.guava", module: "guava"
exclude group: "org.slf4j", module: "slf4j-api"
}
jij ("net.raphimc:MinecraftAuth:4.1.1") {
// RaphiMC Libraries
jij ("net.raphimc:MinecraftAuth:${project.minecraftauth_version}") {
exclude group: "com.google.code.gson", module: "gson"
exclude group: "org.slf4j", module: "slf4j-api"
}
jij "net.lenni0451:Reflect:1.3.4"
jij("net.lenni0451:MCPing:1.4.1") {
// Lenni0451 Libraries
jij "net.lenni0451:Reflect:${project.reflect_version}"
jij("net.lenni0451:MCPing:${project.mcping_version}") {
exclude group: "com.google.code.gson", module: "gson"
}
jij("org.cloudburstmc.netty:netty-transport-raknet:1.0.0.CR3-SNAPSHOT") {
// Misc Libraries
jij("org.cloudburstmc.netty:netty-transport-raknet:${project.raknet_transport_version}") {
exclude group: "io.netty"
}
jij "de.florianmichael:Classic4J:2.1.1-SNAPSHOT"
jij "de.florianmichael:Classic4J:${project.classic4j_version}"
// Fabric's jar in jar system doesn't support transitive dependencies, so we have to manually add them
afterEvaluate {
configurations.jij.incoming.resolutionResult.allDependencies.each {
dependencies.include(dependencies.implementation(dependencies.compileOnlyApi(it.requested.toString()) {
transitive = false
}))
configurations.jij.incoming.resolutionResult.allDependencies {
dependencies.include(dependencies.implementation(dependencies.compileOnlyApi(requested.toString())))
}
}
}
@ -107,21 +108,11 @@ processResources {
filesMatching("fabric.mod.json") {
expand(
"version": project.version,
"description": project.description,
"implVersion": "git-${project.name}-${project.version}:${latestCommitHash()}",
"mcVersion": mcVersion()
"implVersion": "git-${project.name}-${project.version}:${project.latestCommitHash()}",
)
}
}
String mcVersion() {
if (project.supported_versions.isEmpty()) {
return project.minecraft_version
} else {
return project.supported_versions
}
}
String latestCommitHash() {
def stdout = new ByteArrayOutputStream()
exec {
@ -134,8 +125,8 @@ String latestCommitHash() {
java {
withSourcesJar()
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
jar {
@ -161,37 +152,10 @@ publishing {
publications {
maven(MavenPublication) {
groupId = project.maven_group
artifactId = project.maven_name
version = project.maven_version
artifactId = project.archives_base_name
version = project.mod_version
from components.java
pom {
name = artifactId
description = project.description
url = "https://github.com/ViaVersion/ViaFabricPlus"
licenses {
license {
name = "GPL-3.0 License"
url = "https://github.com/ViaVersion/ViaFabricPlus/blob/main/LICENSE"
}
}
developers {
developer {
id = "FlorianMichael"
name = "EnZaXD"
email = "florian.michael07@gmail.com"
}
developer {
id = "RK_01"
}
}
scm {
connection = "scm:git:git://github.com/ViaVersion/ViaFabricPlus.git"
developerConnection = "scm:git:ssh://github.com/ViaVersion/ViaFabricPlus.git"
url = "github.com/ViaVersion/ViaFabricPlus"
}
}
}
}
}

View File

@ -4,23 +4,14 @@ ViaFabricPlus provides various events and APIs for developers to use. This page
## Include via Gradle/Maven
```groovy
repositories {
mavenCentral()
maven {
name = "ViaVersion"
url = "https://repo.viaversion.com"
}
maven {
name = "Lenni0451"
url = "https://maven.lenni0451.net/everything"
}
maven {
name = "OpenCollab Snapshots"
url = "https://repo.opencollab.dev/maven-snapshots/"
}
}
dependencies {
modImplementation("de.florianmichael:ViaFabricPlus:x.x.x") // Get the latest version from releases
modImplementation("de.florianmichael:viafabricplus:x.x.x") // Get the latest version from releases
}
```
@ -30,20 +21,12 @@ dependencies {
<id>viaversion</id>
<url>https://repo.viaversion.com</url>
</repository>
<repository>
<id>lenni0451</id>
<url>https://maven.lenni0451.net/everything</url>
</repository>
<repository>
<id>opencollab-snapshots</id>
<url>https://repo.opencollab.dev/maven-snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>de.florianmichael</groupId>
<artifactId>ViaFabricPlus</artifactId>
<artifactId>viafabricplus</artifactId>
<version>x.x.x</version> <!-- Get the latest version from releases -->
</dependency>
</dependencies>

View File

@ -1,97 +0,0 @@
# Updating instructions for the project
These steps are the usual process for updating ViaFabricPlus to a new version of the game. If you're unsure about something, ask in the ViaVersion discord.
1. Update all upstream versions in `gradle.properties`. The main versions you need to update are:
- `minecraft_version`
- `yarn_version`
- `loader_version`
- `fabric_api_version`
- `supported_versions` (if necessary)
As well as the versions in the `dependencies` block in the `build.gradle` file.
2. Update the `NATIVE_VERSION` field in the ProtocolTranslator class to the new version
3. Check all mixins in the injection package if they still apply correctly, here is a list of some critical ones:
- `MixinClientPlayerEntity#removeBl8Boolean`
- `MixinClientWorld#tickEntity` and `MixinClientWorld#tickPassenger`
- `MixinPlayer#getBlockBreakingSpeed`
4. Decompile the game source code with the tool of your choice.
5. Check all data dumps and diffs in the fixes/data package and update them if necessary, here is a list of some critical ones:
- `ResourcePackHeaderDiff` (add the new version at the top of the list)
- `ItemRegistryDiff` (add all new items/blocks added in the new version)
6. Try to compile the mod and start porting the code until all existing fixes are working again.
7. Diff the game code with the code of the previous version (e.g. using git) and implement all changes that could be relevant for ViaFabricPlus, those are:
- General logic changes (e.g. `if (a && b)` -> `if (b || a)`)
- Changes to the movement code (e.g. `player.yaw` -> `player.headYaw`)
- Networking changes (e.g. sending a new packet / changing the packet structure)
- Changes to visuals (e.g. animation changes)
- Note: ViaVersion already implements most gameplay related changes for us, but you should always check for edge-cases. Since ViaVersion
is primarily a server side plugin, it does not take care of client-side related / deeper changes. ViaFabricPlus often has to inject into
ViaVersion code to improve funcitonality for the client.
**Read more about which fixes should be added [HERE](../CONTRIBUTING.md#adding-protocol-new-fixes---which-are-important-and-which-arent)**
- From experience, the following packages contain the usual important changes:
- `net.minecraft`
- `net.minecraft.client`
- `net.minecraft.client.gui`
- `net.minecraft.client.multiplayer`
- `net.minecraft.client.player`
- `net.minecraft.util`
- `net.minecraft.world`
- `net.minecraft.world.entity`
- `net.minecraft.world.inventory`
- `net.minecraft.world.item`
- `net.minecraft.world.level`
- `net.minecraft.world.level.block`
- While the following packages can be skipped completely (most of the time):
- `com.mojang`
- `net.minecraft.advancements`
- `net.minecraft.commands`
- `net.minecraft.data`
- `net.minecraft.gametest`
- `net.minecraft.realms`
- `net.minecraft.recipebook`
- `net.minecraft.references`
- `net.minecraft.resources`
- `net.minecraft.server`
- `net.minecraft.sounds`
- `net.minecraft.stats`
- `net.minecraft.tags`
8. Update protocol constants in the `ViaFabricPlusProtocol` class
9. Check the ViaVersion/upstream protocol implementation for issues and report them if necessary or if these issues can't be fixed,
without tons of work, implement a workaround in ViaFabricPlus.
10. Run the game and check all GUIs and other visuals for issues.
11. Clean your code and make sure it is readable and understandable, clientside fixes are sorted by their protocol versions, having
newer fixes at the top of the file.
12. Increment the version number in `gradle.properties` by at least a minor version (e.g. 1.0.0 -> 1.1.0)
13. Create a pull request and wait for it to be reviewed and merged.
14. You're done, congrats!
## Git branches
- `main`: The main branch, this is where all changes are merged into
- `dev`: Used for changes which needs reviewing by all developers, usually merged into `main` shortly after
- `update/*`: Update branches, these are used to port ViaFabricPlus to newer versions of the game
- `<version>`: Final release branches sorted by their Minecraft version (e.g. `1.8.9`, `1.16.5`, `1.17.1`, ...)
There are also older formats which aren't used anymore:
- `recode/*`: Recode branches, these are used to port ViaFabricPlus to newer versions of the game or rewrite big parts of the code
- `backport/*`: Backport branches, these are used to backport newer ViaFabricPlus versions to older versions of the game
## Versioning
The versioning should only be updated every release and should only have one update between each release.
- The versioning scheme is `major.minor.patch`, where:
- `major` is incremented when breaking changes are made
- `minor` is incremented when new features are added
- `patch` is incremented when bug fixes are made
This scheme is used as follows:
- `Major` versions are only incremented with breaking and fundamental changes to the existing codebase, such as migrating mappings
or refactoring the entire codebase.
- `Minor` versions are incremented when the mod gets ported to a new version of the game or when huge features are added /
upstream changes are implemented.
- `Patch` versions are incremented when bug fixes are made or small features are added, they are the usual version increment.

View File

@ -0,0 +1,73 @@
# Updating instructions for the project
## Update translation files
Translation files are located in `src/main/resources/assets/viafabricplus/lang/`. To update them, you need to do the following:
1. Copy the `en_us.json` file and rename it to the language code of the language you want to update (e.g. `de_de.json` for German)
2. Translate all values in the file to the language you want to update
3. Do not change the keys of the values, only the values themselves
4. Do not change the formatting of the file (e.g. the spaces between the keys and values or the order of the keys)
5. Try to be consistent with Minecraft language files.
6. Take a look at UN's guidelines for Gender-inclusive language: https://www.un.org/en/gender-inclusive-language/guidelines.shtml
7. Create a pull request and wait for it to be reviewed and merged.
8. You're done, congrats!
## Add a new feature or fix a bug
1. Create a new branch for your feature/bugfix (e.g. `feature/fix-xyz` or `fix/fix-xyz`)
2. Implement your feature/bugfix and make sure it works correctly
3. Clean your code and make sure it is readable and understandable (e.g. use proper variable names)
4. Use the Google java code style (https://google.github.io/styleguide/javaguide.html) and format your code accordingly
5. If you're changing API, make sure to update the documentation in the `docs` folder, add javadocs to your code and don't break backwards compatibility if not necessary
6. Increment the version number in `gradle.properties` by at least a patch version (e.g. 1.0.0 -> 1.0.1)
7. Create a pull request and wait for it to be reviewed and merged.
8. You're done, congrats!
## Setting up a Workspace
ViaFabricPlus uses Gradle, to make sure that it is installed properly you can check [Gradle's website](https://gradle.org/install/).
1. Clone the repository using `git clone https://github.com/ViaVersion/ViaFabricPlus`.
2. CD into the local repository.
3. Run `./gradlew genSources`.
4. Open the folder as a Gradle project in your preferred IDE.
5. Run the mod.
## Update to a new Minecraft version
1. Update all upstream versions in `gradle.properties`. The main versions you need to update are:
- `minecraft_version`
- `yarn_mappings`
- `loader_version`
- `fabric_api_version`
- `viaversion_version`
- `viabackwards_version`
- `mod_menu_version`
2. Update the `NATIVE_VERSION` field in the ProtocolTranslator class to the new version
3. Check all mixins in the injection package if they still apply correctly, here is a list of some critical ones:
- `MixinClientPlayerEntity#removeBl8Boolean`
- `MixinClientWorld#tickEntity` and `MixinClientWorld#tickPassenger`
- `MixinPlayer#getBlockBreakingSpeed`
4. Decompile the game source code with the tool of your choice.
5. Check all data dumps and diffs in the fixes/data package and update them if necessary, here is a list of some critical ones:
- `ResourcePackHeaderDiff` (add the new version at the top of the list)
- `ItemRegistryDiff` (add all new items/blocks added in the new version)
6. Diff the game code with the code of the previous version (e.g. using git) and implement all changes that could be relevant for ViaFabricPlus, those are:
- General logic changes (e.g. `if (a && b)` -> `if (b || a)`)
- Changes to the movement code (e.g. `player.yaw` -> `player.headYaw`)
- Networking changes (e.g. sending a new packet / changing the packet structure)
- Changes to visuals (e.g. animation changes)
- Note: ViaVersion already implements most gameplay related changes for us, but you should always check for edge-cases. Since ViaVersion
is primarily a server side plugin, it does not take care of client-side related / deeper changes.
=> If you are unsure if a change is relevant, ask in the ViaVersion discord, in general you should only implement changes
which could be detected by a server side anti cheat.
7. Check the ViaVersion/upstream protocol implementation for issues and report them if necessary or if these issues can't be fixed,
without tons of work, implement a workaround in ViaFabricPlus.
8. Run the game and check all GUIs and other visuals for issues.
9. Clean your code and make sure it is readable and understandable, clientside fixes are sorted by their protocol versions, having
newer fixes at the top of the file.
10. Increment the version number in `gradle.properties` by at least a minor version (e.g. 1.0.0 -> 1.1.0)
11. Create a pull request and wait for it to be reviewed and merged.
12. You're done, congrats!
## Git branches
- `main`: The main branch, this is where all changes are merged into
- `backport/*`: Backport branches, these are used to backport newer ViaFabricPlus versions to older versions of the game
- `recode/*`: Recode branches, these are used to port ViaFabricPlus to newer versions of the game or rewrite big parts of the code
- `<version>`: Final release branches sorted by their Minecraft version (e.g. `1.8.9`, `1.16.5`, `1.17.1`, ...)

View File

@ -6,12 +6,12 @@ where you can change the settings and set the protocol version, the position of
Settings -> General -> multiplayer screen button orientation.
![](preview/multiplayer.png)
![](preview/protocol_selection.png)
![](preview/protocol.png)
In the Add/Edit Server screen there is a button where you can select a specific version for this server, when you ping or connect to this server,
ViaFabricPlus will use the version set there, the versions are stored in the servers.dat too
![](preview/set_version_for_server.png)
![](preview/force.png)
If you don't want to specify a specific version anymore, you can simply press the button and select **"Cancel and reset"**.
@ -22,18 +22,15 @@ You can use the ViaVersion commands with **/viafabricplus** or **/viaversion**,
### Settings<br>
For users only the settings in the **General**, **Bedrock**, **Authentication** and **Visual** tab are relevant, the other settings are only for developers, you should not change the settings in the **Debug** tab if you don't know what you are doing.
![](preview/settings-selection.png)
The settings are stored in the `settings.json` file. Account credentials for Bedrock/ClassiCube in `accounts.json`.
![](preview/settings.png)
### Configuring the protocol translation libraries
To change the protocol translation settings/features you can look into the config folder. You can find 4 config files there depending on the platforms loaded:
To change the protocol translation settings/features you can look into the ViaLoader folder. You can find 4 config files there depending on the platforms loaded:
- `viaversion.yml` (ViaVersion)
- `viabackwards.yml` (ViaBackwards)
- `vialegacy.yml` (ViaLegacy)
- `viabedrock.yml` (ViaBedrock)
- `viaaprilfools.yml` (ViaAprilFools)
- viaversion.yml (ViaVersion)
- viabackwards.yml (ViaBackwards)
- vialegacy.yml (ViaLegacy)
- viabedrock.yml (ViaBedrock)
On it's first launch, ViaFabricPlus will generate the config files with proper default values. Don't touch the config files if you don't know what you are doing.
@ -45,15 +42,17 @@ The debug HUD can be enabled in the settings, it shows some useful information a
Keep in mind that the Java -> Bedrock support is still in beta phase, and therefore many things are not implemented
yet and there is no guarantee that everything will work as it should.
To log in to a Bedrock account you can press the button **"Click to set account for Bedrock edition"** in the settings.
To log in to a Bedrock account you can press the button **"Click to set account for Bedrock edition"** in the settings,
then you can log in via device login, the account logged in there will be stored in **/minecraft./config/viafabricplus/accounts.json**.
### ClassiCube and BetaCraft integration
In the main GUI there is an extra button for ClassiCube and BetaCraft, both buttons send API requests to the respective platforms to get the respective server list.
## BetaCraft
![](preview/betacraft_servers.png)
![](preview/betacraft.png)
## ClassiCube
![](preview/classicube_servers.png)
![](preview/classicube.png)
For ClassiCube you need an account, which you can make on the official website (https://www.classicube.net/), in case ClassiCube requires MultiFactor, an extra GUI will open in ViaFabricPlus.
![](preview/classicube_login.png)
The ClassiCube account will be stored in **/minecraft./config/viafabricplus/accounts.json**.

View File

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 149 KiB

View File

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 155 KiB

View File

Before

Width:  |  Height:  |  Size: 746 KiB

After

Width:  |  Height:  |  Size: 746 KiB

View File

Before

Width:  |  Height:  |  Size: 130 KiB

After

Width:  |  Height:  |  Size: 130 KiB

View File

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 149 KiB

View File

@ -2,17 +2,34 @@
org.gradle.jvmargs=-Xmx8G
org.gradle.parallel=true
# Project Details
maven_group=de.florianmichael
maven_name=ViaFabricPlus
maven_version=3.4.9-SNAPSHOT
maven_description=Fabric mod to connect to EVERY Minecraft server version (Release, Beta, Alpha, Classic, Snapshots, Bedrock) with QoL fixes to the gameplay
# Minecraft/Fabric
minecraft_version=1.21.1
yarn_version=1.21.1+build.3
loader_version=0.16.5
fabric_api_version=0.103.0+1.21.1
minecraft_version=1.20.4
yarn_mappings=1.20.4+build.3
loader_version=0.15.10
fabric_api_version=0.97.0+1.20.4
# Set to empty to use the Minecraft version above
supported_versions=>=1.21 <=1.21.1
# Project Details
mod_version=3.1.1
maven_group=de.florianmichael
archives_base_name=ViaFabricPlus
# ViaVersion Libraries
viaversion_version=4.10.0
viabackwards_version=4.10.0
vialegacy_version=2.2.22
viaaprilfools_version=2.0.11
vialoader_version=2.2.13
# RaphiMC Libraries
minecraftauth_version=4.0.0
viabedrock_version=0.0.6-SNAPSHOT
raknet_transport_version=1.0.0.CR3-SNAPSHOT
# Lenni0451 Libraries
reflect_version=1.3.2
mcping_version=1.4.0
# Misc Libraries
mod_menu_version=9.0.0
classic4j_version=2.0.2

Binary file not shown.

View File

@ -1,7 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

7
gradlew vendored
View File

@ -15,8 +15,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
#
@ -57,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@ -86,8 +84,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum

186
gradlew.bat vendored
View File

@ -1,94 +1,92 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -1,7 +1,7 @@
# Deploys the latest stable JDK 21 available and sets it to default without having to manually specify it here,
# Deploys the latest stable JDK 17 available and sets it to default without having to manually specify it here,
# Which includes using temurin as the distribution.
before_install:
- curl -s "https://get.sdkman.io" | bash
- source ~/.sdkman/bin/sdkman-init.sh
- sdk install java 21.0.3-tem
- sdk use java 21.0.3-tem
- sdk install java 17.0.10-tem
- sdk use java 17.0.10-tem

View File

@ -33,27 +33,19 @@ import java.io.File;
import java.util.concurrent.CompletableFuture;
/*
* TODO | Port 1.20.6
* - ClientPlayerInteractionManager#interactBlockInternal added new condition
* - Command arguments (Probably not everything worth, but least them with nbt)
* - Entity attachment calculation got changed completely
* - Particle handling has slightly changed
* - BookViewScreen/BookEditScreen networking handling
* - SetEquipment packet now only accepts living entities
* - Wolf interaction
*
* TODO | General
* - Make recipe fixes dynamic instead of a data dump in java classes
* - Check if relevant for protocol translation: TakeItemEntityPacket isEmpty case (1.20 -> 1.20.1 change)
* - Check previous Donkey interaction fix (see git logs)
* - Window interactions in <= 1.16.5 has changed and can be detected by the server
* - Most CTS protocol features aren't supported (see https://github.com/ViaVersion/ViaFabricPlus/issues/181)
* - Most CPE features aren't implemented correctly (see https://github.com/ViaVersion/ViaFabricPlus/issues/152)
* - Via: 1.13 -> 1.12.2 block entities recode
* - OXYGEN_BONUS 1.21 -> 1.20.5 handling is missing (only visual)
* - Check if MixinPlayerScreenHandler.injectTransferSlot is needed? Check git log
*
* TODO | Movement
* - Collision hit boxes has been changed (https://github.com/ViaVersion/ViaFabricPlus/issues/195)
* - Blip-jumping is not supported in <= 1.13.2 (https://github.com/ViaVersion/ViaFabricPlus/issues/225)
* - 1.8 lava movement
* - 1.13.2 water movement
* - Older versions don't clamp positions when teleporting (Is this important?)
*/
public class ViaFabricPlus {
@ -67,20 +59,21 @@ public class ViaFabricPlus {
private CompletableFuture<Void> loadingFuture;
@SuppressWarnings("ResultOfMethodCallIgnored")
public void init() {
directory.mkdir();
ClassLoaderPriorityUtil.loadOverridingJars(directory); // Load overriding jars first so other code can access the new classes
settingsManager = new SettingsManager();
saveManager = new SaveManager(settingsManager);
ClientsideFixes.init(); // Init clientside related fixes
loadingFuture = ProtocolTranslator.init(directory); // Init ViaVersion protocol translator platform
settingsManager = new SettingsManager();
saveManager = new SaveManager(settingsManager);
// Block game loading until ViaVersion has loaded
PostGameLoadCallback.EVENT.register(() -> {
loadingFuture.join();
saveManager.postInit();
saveManager.init();
});
}

View File

@ -21,7 +21,7 @@ package de.florianmichael.viafabricplus.event;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.raphimc.vialegacy.protocol.classic.c0_30cpetoc0_28_30.data.ClassicProtocolExtension;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.data.ClassicProtocolExtension;
/**
* This event is fired when a classic protocol extension is loaded.

View File

@ -19,17 +19,12 @@
package de.florianmichael.viafabricplus.event;
import de.florianmichael.viafabricplus.save.AbstractSave;
import de.florianmichael.viafabricplus.save.SaveManager;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
/**
* This event is fired when loading save files:
* <ul>
* <li>{@link State#PRE} before loading save files</li>
* <li>{@link State#POST} after loading save files</li>
* <li>{@link State#POST_INIT} after loading save files and calling {@link AbstractSave#postInit()} functions</li>
* This event is fired when ViaFabricPlus has loaded its save files, and before it starts reading the values from the save files.
*/
public interface LoadSaveFilesCallback {
@ -42,7 +37,7 @@ public interface LoadSaveFilesCallback {
void onLoadSaveFiles(final SaveManager saveManager, final State state);
enum State {
PRE, POST, POST_INIT
PRE, POST
}
}

View File

@ -20,34 +20,29 @@
package de.florianmichael.viafabricplus.fixes;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.event.*;
import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback;
import de.florianmichael.viafabricplus.event.PostGameLoadCallback;
import de.florianmichael.viafabricplus.fixes.data.EntityDimensionDiff;
import de.florianmichael.viafabricplus.fixes.data.ResourcePackHeaderDiff;
import de.florianmichael.viafabricplus.fixes.versioned.EnchantmentAttributesEmulation1_20_6;
import de.florianmichael.viafabricplus.fixes.versioned.classic.CPEAdditions;
import de.florianmichael.viafabricplus.fixes.versioned.classic.GridItemSelectionScreen;
import de.florianmichael.viafabricplus.fixes.versioned.visual.ArmorHudEmulation1_8;
import de.florianmichael.viafabricplus.fixes.versioned.visual.FootStepParticle1_12_2;
import de.florianmichael.viafabricplus.fixes.versioned.visual.UnicodeFontFix1_12_2;
import de.florianmichael.viafabricplus.injection.access.IClientConnection;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.BedrockSettings;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
import de.florianmichael.viafabricplus.util.DataCustomPayload;
import net.minecraft.block.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.FontStorage;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ServerAddress;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.registry.Registries;
import net.raphimc.viaaprilfools.api.AprilFoolsProtocolVersion;
import net.raphimc.viabedrock.api.BedrockProtocolVersion;
import net.raphimc.viabedrock.protocol.data.ProtocolConstants;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialegacy.protocol.classic.c0_30cpetoc0_28_30.data.ClassicProtocolExtension;
import net.raphimc.vialegacy.protocol.classic.c0_30cpetoc0_28_30.storage.ExtensionProtocolMetadataStorage;
import org.jetbrains.annotations.ApiStatus;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.data.ClassicProtocolExtension;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.storage.ExtensionProtocolMetadataStorage;
import java.util.Map;
import java.util.Objects;
@ -63,33 +58,26 @@ public class ClientsideFixes {
/**
* Contains all tasks that are waiting for a packet to be received, this system can be used to sync ViaVersion tasks with the correct thread
*/
private static final Map<String, Consumer<RegistryByteBuf>> PENDING_EXECUTION_TASKS = new ConcurrentHashMap<>();
private static final Map<String, Consumer<PacketByteBuf>> PENDING_EXECUTION_TASKS = new ConcurrentHashMap<>();
/**
* This identifier is an internal identifier used to identify packets that are sent by ViaFabricPlus
* This identifier is an internal identifier that is used to identify packets that are sent by ViaFabricPlus
*/
@ApiStatus.Internal
public static final String PACKET_SYNC_IDENTIFIER = UUID.randomUUID() + ":" + UUID.randomUUID();
/**
* This is an incremental index used for tablist entries to implement FIFO behavior <= 1.7
* This identifier is an internal identifier used to store the item count in <= 1.10 to implement negative item counts
*/
@ApiStatus.Internal
public static int globalTablistIndex = 0;
public static final String ITEM_COUNT_NBT_TAG = "VFP_1_10_ItemCount_" + System.currentTimeMillis();
static {
public static void init() {
// Register additional CPE features
CPEAdditions.modifyMappings();
// Check if the pack format mappings are correct
ResourcePackHeaderDiff.checkOutdated();
UnicodeFontFix1_12_2.init();
PostGameLoadCallback.EVENT.register(() -> {
// Handle clientside enchantment calculations in <= 1.20.6
EnchantmentAttributesEmulation1_20_6.init();
// Handles and updates entity dimension changes in <= 1.17
EntityDimensionDiff.init();
@ -99,7 +87,11 @@ public class ClientsideFixes {
// Reloads some clientside stuff when the protocol version changes
ChangeProtocolVersionCallback.EVENT.register((oldVersion, newVersion) -> MinecraftClient.getInstance().execute(() -> {
VisualSettings.global().filterNonExistingGlyphs.onValueChanged();
// Clear all font caches to enforce a reload of all fonts (this is needed because we change the font renderer behavior)
for (FontStorage storage : MinecraftClient.getInstance().fontManager.fontStorages.values()) {
storage.glyphRendererCache.clear();
storage.glyphCache.clear();
}
// Reloads all bounding boxes of the blocks that we changed
for (Block block : Registries.BLOCK) {
@ -122,22 +114,10 @@ public class ClientsideFixes {
if (newVersion.olderThanOrEqualTo(LegacyProtocolVersion.c0_28toc0_30)) {
GridItemSelectionScreen.INSTANCE.itemGrid = null;
}
// Reload sound system when switching between 3D Shareware and normal versions
if (oldVersion.equals(AprilFoolsProtocolVersion.s3d_shareware) || newVersion.equals(AprilFoolsProtocolVersion.s3d_shareware)) {
MinecraftClient.getInstance().getSoundManager().reloadSounds();
}
}));
// Register the footstep particle
FootStepParticle1_12_2.init();
// Register the custom payload packet for sync tasks
DataCustomPayload.init();
}
public static void init() {
// Calls the static block
}
/**
@ -171,36 +151,35 @@ public class ClientsideFixes {
* @param version The protocol version
* @return The server address with the replaced default port
*/
public static String replaceDefaultPort(final String address, final ProtocolVersion version) {
public static ServerAddress replaceDefaultPort(final String address, final ProtocolVersion version) {
// If the default port for this entry should be replaced, check if the address already contains a port
// We can't just replace vanilla's default port because a bedrock server might be running on the same port
if (BedrockSettings.global().replaceDefaultPort.getValue() && Objects.equals(version, BedrockProtocolVersion.bedrockLatest) && !address.contains(":")) {
return address + ":" + ProtocolConstants.BEDROCK_DEFAULT_PORT;
return ServerAddress.parse(address + ":" + ProtocolConstants.BEDROCK_DEFAULT_PORT);
} else {
return address;
return ServerAddress.parse(address);
}
}
/**
* Executes a task synchronized with the main thread from networking threads
* Executes a sync task and returns the uuid of the task
*
* @param task The task to execute
* @return The uuid of the task
*/
public static String executeSyncTask(final Consumer<RegistryByteBuf> task) {
public static String executeSyncTask(final Consumer<PacketByteBuf> task) {
final String uuid = UUID.randomUUID().toString();
PENDING_EXECUTION_TASKS.put(uuid, task);
return uuid;
}
@ApiStatus.Internal
public static void handleSyncTask(final PacketByteBuf buf) {
final String uuid = buf.readString();
if (PENDING_EXECUTION_TASKS.containsKey(uuid)) {
MinecraftClient.getInstance().execute(() -> { // Execute the task on the main thread
final var task = PENDING_EXECUTION_TASKS.remove(uuid);
task.accept(new RegistryByteBuf(buf, MinecraftClient.getInstance().getNetworkHandler().getRegistryManager()));
task.accept(buf);
});
}
}

View File

@ -21,13 +21,13 @@ package de.florianmichael.viafabricplus.fixes.data;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.EntityAttachmentType;
import net.minecraft.entity.EntityAttachments;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityType;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import java.util.Collections;
import java.util.Map;
import static de.florianmichael.viafabricplus.util.MapUtil.linkedHashMap;
@ -42,107 +42,105 @@ public class EntityDimensionDiff {
*/
private static final Map<EntityType<?>, Map<ProtocolVersion, EntityDimensions>> ENTITY_DIMENSIONS = linkedHashMap(
EntityType.WITHER, linkedHashMap(
ProtocolVersion.v1_7_6, EntityDimensionsBuilder.create(EntityType.WITHER).withChangingDimensions(0.9F, 4.0F).build(),
ProtocolVersion.v1_7_6, EntityDimensions.changing(0.9F, 4.0F),
ProtocolVersion.v1_8, EntityType.WITHER.getDimensions()
),
EntityType.SILVERFISH, linkedHashMap(
ProtocolVersion.v1_7_6, EntityDimensionsBuilder.create(EntityType.SILVERFISH).withChangingDimensions(0.3F, 0.7F).build(),
ProtocolVersion.v1_7_6, EntityDimensions.changing(0.3F, 0.7F),
ProtocolVersion.v1_8, EntityType.SILVERFISH.getDimensions()
),
EntityType.SNOW_GOLEM, linkedHashMap(
ProtocolVersion.v1_7_6, EntityDimensionsBuilder.create(EntityType.SNOW_GOLEM).withChangingDimensions(0.4F, 1.8F).build(),
ProtocolVersion.v1_7_6, EntityDimensions.changing(0.4F, 1.8F),
ProtocolVersion.v1_8, EntityType.SNOW_GOLEM.getDimensions()
),
EntityType.ZOMBIE, linkedHashMap(
ProtocolVersion.v1_7_6, EntityDimensionsBuilder.create(EntityType.ZOMBIE).withChangingDimensions(0.6F, 1.8F).build(),
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.ZOMBIE).withFixedDimensions(0.6F, 1.95F).build(),
ProtocolVersion.v1_7_6, EntityDimensions.changing(0.6F, 1.8F),
ProtocolVersion.v1_8, EntityDimensions.fixed(EntityType.ZOMBIE.getDimensions().width, EntityType.ZOMBIE.getDimensions().height),
ProtocolVersion.v1_9, EntityType.ZOMBIE.getDimensions()
),
EntityType.CHICKEN, linkedHashMap(
LegacyProtocolVersion.b1_7tob1_7_3, EntityDimensionsBuilder.create(EntityType.CHICKEN).withChangingDimensions(0.3F, 0.4F).build(),
ProtocolVersion.v1_7_6, EntityDimensionsBuilder.create(EntityType.CHICKEN).withChangingDimensions(0.3F, 0.7F).build(),
LegacyProtocolVersion.b1_7tob1_7_3, EntityDimensions.changing(0.3F, 0.4F),
ProtocolVersion.v1_7_6, EntityDimensions.changing(0.3F, 0.7F),
ProtocolVersion.v1_8, EntityType.CHICKEN.getDimensions()
),
EntityType.SHEEP, linkedHashMap(
LegacyProtocolVersion.c0_28toc0_30, EntityDimensionsBuilder.create(EntityType.SHEEP).withChangingDimensions(1.4F, 1.72F).build(),
LegacyProtocolVersion.c0_28toc0_30, EntityDimensions.changing(1.4F, 1.72F),
LegacyProtocolVersion.a1_0_15, EntityType.SHEEP.getDimensions()
),
EntityType.OCELOT, linkedHashMap(
ProtocolVersion.v1_7_6, EntityDimensionsBuilder.create(EntityType.OCELOT).withChangingDimensions(0.6F, 0.8F).build(),
ProtocolVersion.v1_7_6, EntityDimensions.changing(0.6F, 0.8F),
ProtocolVersion.v1_8, EntityType.OCELOT.getDimensions()
),
EntityType.BOAT, linkedHashMap(
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.BOAT).withChangingDimensions(1.5F, 0.6F).build(),
ProtocolVersion.v1_8, EntityDimensions.changing(1.5F, 0.6F),
ProtocolVersion.v1_9, EntityType.BOAT.getDimensions()
),
EntityType.CREEPER, linkedHashMap(
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.CREEPER).withChangingDimensions(0.6F, 1.8F).build(),
ProtocolVersion.v1_8, EntityDimensions.changing(0.6F, 1.8F),
ProtocolVersion.v1_9, EntityType.CREEPER.getDimensions()
),
EntityType.IRON_GOLEM, linkedHashMap(
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.IRON_GOLEM).withChangingDimensions(1.4F, 2.9F).build(),
ProtocolVersion.v1_8, EntityDimensions.changing(1.4F, 2.9F),
ProtocolVersion.v1_9, EntityType.IRON_GOLEM.getDimensions()
),
EntityType.SKELETON, linkedHashMap(
ProtocolVersion.v1_7_6, EntityDimensionsBuilder.create(EntityType.SKELETON).withChangingDimensions(0.6F, 1.8F).build(),
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.SKELETON).withChangingDimensions(0.6F, 1.95F).build(),
ProtocolVersion.v1_7_6, EntityDimensions.changing(0.6F, 1.8F),
ProtocolVersion.v1_8, EntityDimensions.changing(0.6F, 1.95F),
ProtocolVersion.v1_9, EntityType.SKELETON.getDimensions()
),
EntityType.WITHER_SKELETON, linkedHashMap(
LegacyProtocolVersion.r1_4_6tor1_4_7, EntityDimensionsBuilder.create(EntityType.WITHER_SKELETON).withChangingDimensions(0.72F, 2.16F).build(),
ProtocolVersion.v1_7_6, EntityDimensionsBuilder.create(EntityType.WITHER_SKELETON).withChangingDimensions(0.72F, 2.34F).build(),
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.WITHER_SKELETON).withChangingDimensions(0.72F, 2.535F).build(),
LegacyProtocolVersion.r1_4_6tor1_4_7, EntityDimensions.changing(0.72F, 2.16F),
ProtocolVersion.v1_7_6, EntityDimensions.changing(0.72F, 2.34F),
ProtocolVersion.v1_8, EntityDimensions.changing(0.72F, 2.535F),
ProtocolVersion.v1_9, EntityType.WITHER_SKELETON.getDimensions()
),
EntityType.COW, linkedHashMap(
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.COW).withChangingDimensions(0.9F, 1.3F).build(),
ProtocolVersion.v1_8, EntityDimensions.changing(0.9F, 1.3F),
ProtocolVersion.v1_9, EntityType.COW.getDimensions()
),
EntityType.HORSE, linkedHashMap(
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.HORSE).withChangingDimensions(1.4F, 1.6F).build(),
ProtocolVersion.v1_8, EntityDimensions.changing(1.4F, 1.6F),
ProtocolVersion.v1_9, EntityType.HORSE.getDimensions()
),
EntityType.MOOSHROOM, linkedHashMap(
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.MOOSHROOM).withChangingDimensions(0.9F, 1.3F).build(),
ProtocolVersion.v1_8, EntityDimensions.changing(0.9F, 1.3F),
ProtocolVersion.v1_9, EntityType.MOOSHROOM.getDimensions()
),
EntityType.RABBIT, linkedHashMap(
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.RABBIT).withChangingDimensions(0.6F, 0.7F).build(),
ProtocolVersion.v1_8, EntityDimensions.changing(0.6F, 0.7F),
ProtocolVersion.v1_9, EntityType.RABBIT.getDimensions()
),
EntityType.SQUID, linkedHashMap(
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.SQUID).withChangingDimensions(0.95F, 0.95F).build(),
ProtocolVersion.v1_8, EntityDimensions.changing(0.95F, 0.95F),
ProtocolVersion.v1_9, EntityType.SQUID.getDimensions()
),
EntityType.VILLAGER, linkedHashMap(
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.VILLAGER).withChangingDimensions(0.6F, 1.8F).build(),
ProtocolVersion.v1_8, EntityDimensions.changing(0.6F, 1.8F),
ProtocolVersion.v1_9, EntityType.VILLAGER.getDimensions()
),
EntityType.WOLF, linkedHashMap(
LegacyProtocolVersion.r1_1, EntityDimensionsBuilder.create(EntityType.WOLF).withChangingDimensions(0.8F, 0.8F).build(),
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.WOLF).withChangingDimensions(0.6F, 0.8F).build(),
LegacyProtocolVersion.r1_1, EntityDimensions.changing(0.8F, 0.8F),
ProtocolVersion.v1_8, EntityDimensions.changing(0.6F, 0.8F),
ProtocolVersion.v1_9, EntityType.WOLF.getDimensions()
),
EntityType.DRAGON_FIREBALL, linkedHashMap(
ProtocolVersion.v1_10, EntityDimensionsBuilder.create(EntityType.DRAGON_FIREBALL).withChangingDimensions(0.3125F, 0.3125F).build(),
ProtocolVersion.v1_10, EntityDimensions.changing(0.3125F, 0.3125F),
ProtocolVersion.v1_11, EntityType.DRAGON_FIREBALL.getDimensions()
),
EntityType.LEASH_KNOT, linkedHashMap(
ProtocolVersion.v1_16_4, EntityDimensionsBuilder.create(EntityType.LEASH_KNOT).withChangingDimensions(0.5F, 0.5F).build(),
ProtocolVersion.v1_16_4, EntityDimensions.changing(0.5F, 0.5F),
ProtocolVersion.v1_17, EntityType.LEASH_KNOT.getDimensions()
),
EntityType.SLIME, linkedHashMap(
ProtocolVersion.v1_13_2, EntityDimensionsBuilder.create(EntityType.SLIME).withChangingDimensions(2F * 0.255F, 2F * 0.255F).build(),
ProtocolVersion.v1_14, EntityDimensionsBuilder.create(EntityType.SLIME).withChangingDimensions(2.04F * 0.255F, 2.04F * 0.255F).build(),
ProtocolVersion.v1_20_5, EntityType.SLIME.getDimensions()
ProtocolVersion.v1_13_2, EntityDimensions.changing(2F, 2F),
ProtocolVersion.v1_14, EntityType.SLIME.getDimensions()
),
EntityType.MAGMA_CUBE, linkedHashMap(
ProtocolVersion.v1_13_2, EntityDimensionsBuilder.create(EntityType.MAGMA_CUBE).withChangingDimensions(2F * 0.255F, 2F * 0.255F).build(),
ProtocolVersion.v1_14, EntityDimensionsBuilder.create(EntityType.MAGMA_CUBE).withChangingDimensions(2.04F * 0.255F, 2.04F * 0.255F).build(),
ProtocolVersion.v1_20_5, EntityType.MAGMA_CUBE.getDimensions()
ProtocolVersion.v1_13_2, EntityDimensions.changing(2F, 2F),
ProtocolVersion.v1_14, EntityType.MAGMA_CUBE.getDimensions()
),
EntityType.ARROW, linkedHashMap(
LegacyProtocolVersion.c0_28toc0_30, EntityDimensionsBuilder.create(EntityType.ARROW).withChangingDimensions(0.3F, 0.5F).build(),
LegacyProtocolVersion.c0_28toc0_30, EntityDimensions.changing(0.3F, 0.5F),
LegacyProtocolVersion.a1_0_15, EntityType.ARROW.getDimensions()
)
);
@ -164,52 +162,50 @@ public class EntityDimensionDiff {
}
public static void init() {
// Calls the static block
// Loads the class and triggers the static initializer.
}
private static class EntityDimensionsBuilder {
/**
* @param entityType The {@link EntityType} to get the dimensions for.
* @return The dimensions for the given {@link EntityType} or null if there are none. The map is unmodifiable.
*/
public static Map<ProtocolVersion, EntityDimensions> getEntityDimensions(final EntityType<?> entityType) {
if (!ENTITY_DIMENSIONS.containsKey(entityType)) {
return null;
}
return Collections.unmodifiableMap(ENTITY_DIMENSIONS.get(entityType));
}
private EntityDimensions entityDimensions;
private EntityAttachments.Builder attachments = EntityAttachments.builder();
public static EntityDimensionsBuilder create() {
return new EntityDimensionsBuilder();
/**
* @param entityType The {@link EntityType} to get the dimensions for.
* @param version The {@link ProtocolVersion} to get the dimensions for.
* @return The closest dimensions for the given {@link EntityType} and {@link ProtocolVersion} or null if there are none.
*/
public static EntityDimensions getEntityDimensions(final EntityType<?> entityType, final ProtocolVersion version) {
final Map<ProtocolVersion, EntityDimensions> dimensionMap = getEntityDimensions(entityType);
if (dimensionMap == null) {
return null;
}
public static EntityDimensionsBuilder create(final EntityType<?> template) {
final EntityDimensionsBuilder entityDimensionsBuilder = new EntityDimensionsBuilder();
entityDimensionsBuilder.entityDimensions = template.getDimensions();
return entityDimensionsBuilder;
}
EntityDimensions closestDimensions = null;
ProtocolVersion closestVersion = null;
public EntityDimensionsBuilder withChangingDimensions(final float width, final float height) {
this.entityDimensions = new EntityDimensions(width, height, this.entityDimensions.eyeHeight(), this.entityDimensions.attachments(), false);
return this;
}
for (Map.Entry<ProtocolVersion, EntityDimensions> entry : dimensionMap.entrySet()) {
final var currentVersion = entry.getKey();
final var currentDimensions = entry.getValue();
public EntityDimensionsBuilder withFixedDimensions(final float width, final float height) {
this.entityDimensions = new EntityDimensions(width, height, this.entityDimensions.eyeHeight(), this.entityDimensions.attachments(), true);
return this;
}
public EntityDimensionsBuilder withEyeHeight(final float eyeHeight) {
this.entityDimensions = this.entityDimensions.withEyeHeight(eyeHeight);
return this;
}
public EntityDimensionsBuilder withPassengerAttachments(final float... offsetYs) {
for (float f : offsetYs) {
this.attachments = this.attachments.add(EntityAttachmentType.PASSENGER, 0.0F, f, 0.0F);
if (currentVersion == version) { // If the version is exactly the same, return the dimensions
return currentDimensions;
}
this.entityDimensions = this.entityDimensions.withAttachments(this.attachments);
return this;
}
public EntityDimensions build() {
return this.entityDimensions;
// If the current version is closer to the version you are looking for
if (closestVersion == null || ProtocolTranslator.isCloserTo(version, currentVersion, closestVersion)) {
closestVersion = currentVersion;
closestDimensions = currentDimensions;
}
}
return closestDimensions;
}
}

View File

@ -25,8 +25,8 @@ import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.item.Item;
import net.raphimc.vialegacy.protocol.classic.c0_30cpetoc0_28_30.data.ClassicProtocolExtension;
import net.raphimc.vialegacy.protocol.classic.c0_30cpetoc0_28_30.storage.ExtensionProtocolMetadataStorage;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.data.ClassicProtocolExtension;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.storage.ExtensionProtocolMetadataStorage;
import net.raphimc.vialoader.util.VersionRange;
import java.util.ArrayList;
@ -48,86 +48,6 @@ public class ItemRegistryDiff {
public static final List<Item> EXTENDED_CLASSIC_ITEMS = new ArrayList<>();
static {
ITEM_DIFF.put(MUSIC_DISC_CREATOR_MUSIC_BOX, andNewer(v1_21));
ITEM_DIFF.put(MUSIC_DISC_CREATOR, andNewer(v1_21));
ITEM_DIFF.put(MUSIC_DISC_PRECIPICE, andNewer(v1_21));
ITEM_DIFF.put(TUFF_SLAB, andNewer(v1_20_5));
ITEM_DIFF.put(TUFF_STAIRS, andNewer(v1_20_5));
ITEM_DIFF.put(TUFF_WALL, andNewer(v1_20_5));
ITEM_DIFF.put(CHISELED_TUFF, andNewer(v1_20_5));
ITEM_DIFF.put(POLISHED_TUFF, andNewer(v1_20_5));
ITEM_DIFF.put(POLISHED_TUFF_SLAB, andNewer(v1_20_5));
ITEM_DIFF.put(POLISHED_TUFF_STAIRS, andNewer(v1_20_5));
ITEM_DIFF.put(POLISHED_TUFF_WALL, andNewer(v1_20_5));
ITEM_DIFF.put(TUFF_BRICKS, andNewer(v1_20_5));
ITEM_DIFF.put(TUFF_BRICK_SLAB, andNewer(v1_20_5));
ITEM_DIFF.put(TUFF_BRICK_STAIRS, andNewer(v1_20_5));
ITEM_DIFF.put(TUFF_BRICK_WALL, andNewer(v1_20_5));
ITEM_DIFF.put(CHISELED_TUFF_BRICKS, andNewer(v1_20_5));
ITEM_DIFF.put(HEAVY_CORE, andNewer(v1_20_5));
ITEM_DIFF.put(CHISELED_COPPER, andNewer(v1_20_5));
ITEM_DIFF.put(EXPOSED_CHISELED_COPPER, andNewer(v1_20_5));
ITEM_DIFF.put(WEATHERED_CHISELED_COPPER, andNewer(v1_20_5));
ITEM_DIFF.put(OXIDIZED_CHISELED_COPPER, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_CHISELED_COPPER, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_EXPOSED_CHISELED_COPPER, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_WEATHERED_CHISELED_COPPER, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_OXIDIZED_CHISELED_COPPER, andNewer(v1_20_5));
ITEM_DIFF.put(COPPER_DOOR, andNewer(v1_20_5));
ITEM_DIFF.put(EXPOSED_COPPER_DOOR, andNewer(v1_20_5));
ITEM_DIFF.put(WEATHERED_COPPER_DOOR, andNewer(v1_20_5));
ITEM_DIFF.put(OXIDIZED_COPPER_DOOR, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_COPPER_DOOR, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_EXPOSED_COPPER_DOOR, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_WEATHERED_COPPER_DOOR, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_OXIDIZED_COPPER_DOOR, andNewer(v1_20_5));
ITEM_DIFF.put(COPPER_TRAPDOOR, andNewer(v1_20_5));
ITEM_DIFF.put(EXPOSED_COPPER_TRAPDOOR, andNewer(v1_20_5));
ITEM_DIFF.put(WEATHERED_COPPER_TRAPDOOR, andNewer(v1_20_5));
ITEM_DIFF.put(OXIDIZED_COPPER_TRAPDOOR, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_COPPER_TRAPDOOR, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_EXPOSED_COPPER_TRAPDOOR, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_WEATHERED_COPPER_TRAPDOOR, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_OXIDIZED_COPPER_TRAPDOOR, andNewer(v1_20_5));
ITEM_DIFF.put(ARMADILLO_SCUTE, andNewer(v1_20_5));
ITEM_DIFF.put(WOLF_ARMOR, andNewer(v1_20_5));
ITEM_DIFF.put(CRAFTER, andNewer(v1_20_5));
ITEM_DIFF.put(ARMADILLO_SPAWN_EGG, andNewer(v1_20_5));
ITEM_DIFF.put(BOGGED_SPAWN_EGG, andNewer(v1_20_5));
ITEM_DIFF.put(BREEZE_SPAWN_EGG, andNewer(v1_20_5));
ITEM_DIFF.put(WIND_CHARGE, andNewer(v1_20_5));
ITEM_DIFF.put(MACE, andNewer(v1_20_5));
ITEM_DIFF.put(FLOW_BANNER_PATTERN, andNewer(v1_20_5));
ITEM_DIFF.put(GUSTER_BANNER_PATTERN, andNewer(v1_20_5));
ITEM_DIFF.put(FLOW_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(v1_20_5));
ITEM_DIFF.put(BOLT_ARMOR_TRIM_SMITHING_TEMPLATE, andNewer(v1_20_5));
ITEM_DIFF.put(FLOW_POTTERY_SHERD, andNewer(v1_20_5));
ITEM_DIFF.put(GUSTER_POTTERY_SHERD, andNewer(v1_20_5));
ITEM_DIFF.put(SCRAPE_POTTERY_SHERD, andNewer(v1_20_5));
ITEM_DIFF.put(COPPER_GRATE, andNewer(v1_20_5));
ITEM_DIFF.put(EXPOSED_COPPER_GRATE, andNewer(v1_20_5));
ITEM_DIFF.put(WEATHERED_COPPER_GRATE, andNewer(v1_20_5));
ITEM_DIFF.put(OXIDIZED_COPPER_GRATE, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_COPPER_GRATE, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_EXPOSED_COPPER_GRATE, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_WEATHERED_COPPER_GRATE, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_OXIDIZED_COPPER_GRATE, andNewer(v1_20_5));
ITEM_DIFF.put(COPPER_BULB, andNewer(v1_20_5));
ITEM_DIFF.put(EXPOSED_COPPER_BULB, andNewer(v1_20_5));
ITEM_DIFF.put(WEATHERED_COPPER_BULB, andNewer(v1_20_5));
ITEM_DIFF.put(OXIDIZED_COPPER_BULB, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_COPPER_BULB, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_EXPOSED_COPPER_BULB, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_WEATHERED_COPPER_BULB, andNewer(v1_20_5));
ITEM_DIFF.put(WAXED_OXIDIZED_COPPER_BULB, andNewer(v1_20_5));
ITEM_DIFF.put(TRIAL_SPAWNER, andNewer(v1_20_5));
ITEM_DIFF.put(TRIAL_KEY, andNewer(v1_20_5));
ITEM_DIFF.put(OMINOUS_TRIAL_KEY, andNewer(v1_20_5));
ITEM_DIFF.put(VAULT, andNewer(v1_20_5));
ITEM_DIFF.put(OMINOUS_BOTTLE, andNewer(v1_20_5));
ITEM_DIFF.put(BREEZE_ROD, andNewer(v1_20_5));
ITEM_DIFF.put(CHERRY_LOG, andNewer(v1_20));
ITEM_DIFF.put(CHERRY_WOOD, andNewer(v1_20));
ITEM_DIFF.put(STRIPPED_CHERRY_LOG, andNewer(v1_20));
@ -684,7 +604,7 @@ public class ItemRegistryDiff {
ITEM_DIFF.put(BLUE_ICE, andNewer(v1_13));
ITEM_DIFF.put(CONDUIT, andNewer(v1_13));
ITEM_DIFF.put(TURTLE_HELMET, andNewer(v1_13));
ITEM_DIFF.put(TURTLE_SCUTE, andNewer(v1_13));
ITEM_DIFF.put(SCUTE, andNewer(v1_13));
ITEM_DIFF.put(PUFFERFISH_BUCKET, andNewer(v1_13));
ITEM_DIFF.put(SALMON_BUCKET, andNewer(v1_13));
ITEM_DIFF.put(COD_BUCKET, andNewer(v1_13));

File diff suppressed because it is too large Load Diff

View File

@ -20,12 +20,11 @@
package de.florianmichael.viafabricplus.fixes.data;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import com.viaversion.viaversion.api.protocol.version.VersionType;
import net.minecraft.GameVersion;
import net.minecraft.SaveVersion;
import net.minecraft.SharedConstants;
import net.minecraft.resource.ResourceType;
import org.jetbrains.annotations.ApiStatus;
import java.util.Date;
import java.util.HashMap;
@ -39,8 +38,7 @@ public class ResourcePackHeaderDiff {
private final static Map<ProtocolVersion, GameVersion> GAME_VERSION_DIFF = new HashMap<>();
static {
registerVersion(ProtocolVersion.v1_21, 34, "1.21.1");
registerVersion(ProtocolVersion.v1_20_5, 32, "1.20.6");
registerVersion(ProtocolVersion.v1_20_5, 32, "1.20.5");
registerVersion(ProtocolVersion.v1_20_3, 22, "1.20.4");
registerVersion(ProtocolVersion.v1_20_2, 18, "1.20.2");
registerVersion(ProtocolVersion.v1_20, 15, "1.20.1");
@ -83,10 +81,16 @@ public class ResourcePackHeaderDiff {
registerVersion(ProtocolVersion.v1_7_2, 1, "1.7.5");
}
@ApiStatus.Internal
/**
* Checks if the registry is outdated.
*/
public static void checkOutdated() {
if (!GAME_VERSION_DIFF.containsKey(ProtocolTranslator.NATIVE_VERSION)) {
throw new RuntimeException("The native client version is not registered in the resource pack header diff!");
for (ProtocolVersion version : ProtocolVersion.getProtocols()) {
if (version.isSnapshot()) continue;
if (version.getVersionType() != VersionType.RELEASE) continue;
if (!GAME_VERSION_DIFF.containsKey(version)) {
throw new RuntimeException("The version " + version + " has no pack format registered");
}
}
}

View File

@ -21,19 +21,19 @@ package de.florianmichael.viafabricplus.fixes.data.recipe;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.BannerPatternsComponent;
import net.minecraft.block.entity.BannerBlockEntity;
import net.minecraft.inventory.RecipeInputInventory;
import net.minecraft.item.BannerItem;
import net.minecraft.item.DyeItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtList;
import net.minecraft.recipe.RecipeSerializer;
import net.minecraft.recipe.SpecialCraftingRecipe;
import net.minecraft.recipe.SpecialRecipeSerializer;
import net.minecraft.recipe.book.CraftingRecipeCategory;
import net.minecraft.recipe.input.CraftingRecipeInput;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.util.DyeColor;
import net.minecraft.world.World;
@ -46,14 +46,14 @@ public class AddBannerPatternRecipe extends SpecialCraftingRecipe {
}
@Override
public boolean matches(CraftingRecipeInput inv, World world) {
public boolean matches(RecipeInputInventory inv, World world) {
boolean foundBanner = false;
for (int i = 0; i < inv.getSize(); i++) {
ItemStack stack = inv.getStackInSlot(i);
for (int i = 0; i < inv.size(); i++) {
ItemStack stack = inv.getStack(i);
if (stack.getItem() instanceof BannerItem) {
if (foundBanner)
return false;
if (stack.getOrDefault(DataComponentTypes.BANNER_PATTERNS, BannerPatternsComponent.DEFAULT).layers().size() >= 6)
if (BannerBlockEntity.getPatternCount(stack) >= 6)
return false;
foundBanner = true;
}
@ -62,11 +62,11 @@ public class AddBannerPatternRecipe extends SpecialCraftingRecipe {
}
@Override
public ItemStack craft(CraftingRecipeInput inv, RegistryWrapper.WrapperLookup lookup) {
public ItemStack craft(RecipeInputInventory inv, DynamicRegistryManager registryManager) {
ItemStack result = ItemStack.EMPTY;
for (int i = 0; i < inv.getSize(); i++) {
ItemStack stack = inv.getStackInSlot(i);
for (int i = 0; i < inv.size(); i++) {
ItemStack stack = inv.getStack(i);
if (!stack.isEmpty() && stack.getItem() instanceof BannerItem) {
result = stack.copy();
result.setCount(1);
@ -74,23 +74,28 @@ public class AddBannerPatternRecipe extends SpecialCraftingRecipe {
}
}
final BannerPattern_1_13_2 pattern = getBannerPattern(inv);
BannerPattern_1_13_2 pattern = getBannerPattern(inv);
if (pattern != null) {
final var patternKey = lookup.getWrapperOrThrow(RegistryKeys.BANNER_PATTERN).getOrThrow(pattern.getKey());
DyeColor color = ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_12_2) ? DyeColor.BLACK : DyeColor.WHITE;
for (int i = 0; i < inv.getSize(); i++) {
Item item = inv.getStackInSlot(i).getItem();
for (int i = 0; i < inv.size(); i++) {
Item item = inv.getStack(i).getItem();
if (item instanceof DyeItem dyeItem) {
color = dyeItem.getColor();
}
}
final BannerPatternsComponent.Builder patternsBuilder = new BannerPatternsComponent.Builder();
if (result.contains(DataComponentTypes.BANNER_PATTERNS)) {
patternsBuilder.addAll(result.get(DataComponentTypes.BANNER_PATTERNS));
NbtCompound tileEntityNbt = result.getOrCreateSubNbt("BlockEntityTag");
NbtList patterns;
if (tileEntityNbt.contains("Patterns", 9)) {
patterns = tileEntityNbt.getList("Patterns", 10);
} else {
patterns = new NbtList();
tileEntityNbt.put("Patterns", patterns);
}
patternsBuilder.add(new BannerPatternsComponent.Layer(patternKey, color));
result.set(DataComponentTypes.BANNER_PATTERNS, patternsBuilder.build());
NbtCompound patternNbt = new NbtCompound();
patternNbt.putString("Pattern", pattern.getId());
patternNbt.putInt("Color", color.getId());
patterns.add(patternNbt);
}
return result;
@ -106,7 +111,7 @@ public class AddBannerPatternRecipe extends SpecialCraftingRecipe {
return SERIALIZER;
}
private static BannerPattern_1_13_2 getBannerPattern(CraftingRecipeInput inv) {
private static BannerPattern_1_13_2 getBannerPattern(RecipeInputInventory inv) {
for (BannerPattern_1_13_2 pattern : BannerPattern_1_13_2.values()) {
if (!pattern.isCraftable())
continue;
@ -115,8 +120,8 @@ public class AddBannerPatternRecipe extends SpecialCraftingRecipe {
if (pattern.hasBaseStack()) {
boolean foundBaseItem = false;
boolean foundDye = false;
for (int i = 0; i < inv.getSize(); i++) {
ItemStack stack = inv.getStackInSlot(i);
for (int i = 0; i < inv.size(); i++) {
ItemStack stack = inv.getStack(i);
if (!stack.isEmpty() && !(stack.getItem() instanceof BannerItem)) {
if (stack.getItem() instanceof DyeItem) {
if (foundDye) {
@ -134,12 +139,12 @@ public class AddBannerPatternRecipe extends SpecialCraftingRecipe {
}
}
if (!foundBaseItem || (!foundDye && ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_10))) matches = false;
} else if (inv.getSize() == pattern.getRecipePattern().length * pattern.getRecipePattern()[0].length()) {
} else if (inv.size() == pattern.getRecipePattern().length * pattern.getRecipePattern()[0].length()) {
DyeColor patternColor = null;
for (int i = 0; i < inv.getSize(); i++) {
for (int i = 0; i < inv.size(); i++) {
int row = i / 3;
int col = i % 3;
ItemStack stack = inv.getStackInSlot(i);
ItemStack stack = inv.getStack(i);
Item item = stack.getItem();
if (!stack.isEmpty() && !(item instanceof BannerItem)) {
if (!(item instanceof DyeItem)) {

View File

@ -20,79 +20,76 @@
package de.florianmichael.viafabricplus.fixes.data.recipe;
import net.minecraft.block.Blocks;
import net.minecraft.block.entity.BannerPattern;
import net.minecraft.block.entity.BannerPatterns;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.registry.RegistryKey;
public enum BannerPattern_1_13_2 {
BASE(BannerPatterns.BASE),
SQUARE_BOTTOM_LEFT(BannerPatterns.SQUARE_BOTTOM_LEFT, " ", " ", "# "),
SQUARE_BOTTOM_RIGHT(BannerPatterns.SQUARE_BOTTOM_RIGHT, " ", " ", " #"),
SQUARE_TOP_LEFT(BannerPatterns.SQUARE_TOP_LEFT, "# ", " ", " "),
SQUARE_TOP_RIGHT(BannerPatterns.SQUARE_TOP_RIGHT, " #", " ", " "),
STRIPE_BOTTOM(BannerPatterns.STRIPE_BOTTOM, " ", " ", "###"),
STRIPE_TOP(BannerPatterns.STRIPE_TOP, "###", " ", " "),
STRIPE_LEFT(BannerPatterns.STRIPE_LEFT, "# ", "# ", "# "),
STRIPE_RIGHT(BannerPatterns.STRIPE_RIGHT, " #", " #", " #"),
STRIPE_CENTER(BannerPatterns.STRIPE_CENTER, " # ", " # ", " # "),
STRIPE_MIDDLE(BannerPatterns.STRIPE_MIDDLE, " ", "###", " "),
STRIPE_DOWNRIGHT(BannerPatterns.STRIPE_DOWNRIGHT, "# ", " # ", " #"),
STRIPE_DOWNLEFT(BannerPatterns.STRIPE_DOWNLEFT, " #", " # ", "# "),
STRIPE_SMALL(BannerPatterns.SMALL_STRIPES, "# #", "# #", " "),
CROSS(BannerPatterns.CROSS, "# #", " # ", "# #"),
STRAIGHT_CROSS(BannerPatterns.STRAIGHT_CROSS, " # ", "###", " # "),
TRIANGLE_BOTTOM(BannerPatterns.TRIANGLE_BOTTOM, " ", " # ", "# #"),
TRIANGLE_TOP(BannerPatterns.TRIANGLE_TOP, "# #", " # ", " "),
TRIANGLES_BOTTOM(BannerPatterns.TRIANGLES_BOTTOM, " ", "# #", " # "),
TRIANGLES_TOP(BannerPatterns.TRIANGLES_TOP, " # ", "# #", " "),
DIAGONAL_LEFT(BannerPatterns.DIAGONAL_LEFT, "## ", "# ", " "),
DIAGONAL_RIGHT(BannerPatterns.DIAGONAL_RIGHT, " ", " #", " ##"),
DIAGONAL_LEFT_MIRROR(BannerPatterns.DIAGONAL_UP_LEFT, " ", "# ", "## "),
DIAGONAL_RIGHT_MIRROR(BannerPatterns.DIAGONAL_UP_RIGHT, " ##", " #", " "),
CIRCLE_MIDDLE(BannerPatterns.CIRCLE, " ", " # ", " "),
RHOMBUS_MIDDLE(BannerPatterns.RHOMBUS, " # ", "# #", " # "),
HALF_VERTICAL(BannerPatterns.HALF_VERTICAL, "## ", "## ", "## "),
HALF_HORIZONTAL(BannerPatterns.HALF_HORIZONTAL, "###", "###", " "),
HALF_VERTICAL_MIRROR(BannerPatterns.HALF_VERTICAL_RIGHT, " ##", " ##", " ##"),
HALF_HORIZONTAL_MIRROR(BannerPatterns.HALF_HORIZONTAL_BOTTOM, " ", "###", "###"),
BORDER(BannerPatterns.BORDER, "###", "# #", "###"),
CURLY_BORDER(BannerPatterns.CURLY_BORDER, new ItemStack(Blocks.VINE)),
GRADIENT(BannerPatterns.GRADIENT, "# #", " # ", " # "),
GRADIENT_UP(BannerPatterns.GRADIENT_UP, " # ", " # ", "# #"),
BRICKS(BannerPatterns.BRICKS, new ItemStack(Blocks.BRICKS)),
GLOBE(BannerPatterns.GLOBE),
CREEPER(BannerPatterns.CREEPER, new ItemStack(Items.CREEPER_HEAD)),
SKULL(BannerPatterns.SKULL, new ItemStack(Items.WITHER_SKELETON_SKULL)),
FLOWER(BannerPatterns.FLOWER, new ItemStack(Blocks.OXEYE_DAISY)),
MOJANG(BannerPatterns.MOJANG, new ItemStack(Items.ENCHANTED_GOLDEN_APPLE));
BASE("b"),
SQUARE_BOTTOM_LEFT("bl", " ", " ", "# "),
SQUARE_BOTTOM_RIGHT("br", " ", " ", " #"),
SQUARE_TOP_LEFT("tl", "# ", " ", " "),
SQUARE_TOP_RIGHT("tr", " #", " ", " "),
STRIPE_BOTTOM("bs", " ", " ", "###"),
STRIPE_TOP("ts", "###", " ", " "),
STRIPE_LEFT("ls", "# ", "# ", "# "),
STRIPE_RIGHT("rs", " #", " #", " #"),
STRIPE_CENTER("cs", " # ", " # ", " # "),
STRIPE_MIDDLE("ms", " ", "###", " "),
STRIPE_DOWNRIGHT("drs", "# ", " # ", " #"),
STRIPE_DOWNLEFT("dls", " #", " # ", "# "),
STRIPE_SMALL("ss", "# #", "# #", " "),
CROSS("cr", "# #", " # ", "# #"),
STRAIGHT_CROSS("sc", " # ", "###", " # "),
TRIANGLE_BOTTOM("bt", " ", " # ", "# #"),
TRIANGLE_TOP("tt", "# #", " # ", " "),
TRIANGLES_BOTTOM("bts", " ", "# #", " # "),
TRIANGLES_TOP("tts", " # ", "# #", " "),
DIAGONAL_LEFT("ld", "## ", "# ", " "),
DIAGONAL_RIGHT("rd", " ", " #", " ##"),
DIAGONAL_LEFT_MIRROR("lud", " ", "# ", "## "),
DIAGONAL_RIGHT_MIRROR("rud", " ##", " #", " "),
CIRCLE_MIDDLE("mc", " ", " # ", " "),
RHOMBUS_MIDDLE("mr", " # ", "# #", " # "),
HALF_VERTICAL("vh", "## ", "## ", "## "),
HALF_HORIZONTAL("hh", "###", "###", " "),
HALF_VERTICAL_MIRROR("vhr", " ##", " ##", " ##"),
HALF_HORIZONTAL_MIRROR("hhb", " ", "###", "###"),
BORDER("bo", "###", "# #", "###"),
CURLY_BORDER("cbo", new ItemStack(Blocks.VINE)),
GRADIENT("gra", "# #", " # ", " # "),
GRADIENT_UP("gru", " # ", " # ", "# #"),
BRICKS("bri", new ItemStack(Blocks.BRICKS)),
GLOBE("glb"),
CREEPER("cre", new ItemStack(Items.CREEPER_HEAD)),
SKULL("sku", new ItemStack(Items.WITHER_SKELETON_SKULL)),
FLOWER("flo", new ItemStack(Blocks.OXEYE_DAISY)),
MOJANG("moj", new ItemStack(Items.ENCHANTED_GOLDEN_APPLE));
private final RegistryKey<BannerPattern> pattern;
private final String id;
private final String[] recipePattern;
private ItemStack baseStack;
BannerPattern_1_13_2(final RegistryKey<BannerPattern> pattern) {
BannerPattern_1_13_2(String id) {
this.recipePattern = new String[3];
this.baseStack = ItemStack.EMPTY;
this.pattern = pattern;
this.id = id;
}
BannerPattern_1_13_2(final RegistryKey<BannerPattern> pattern, final ItemStack baseStack) {
this(pattern);
BannerPattern_1_13_2(String id, ItemStack baseStack) {
this(id);
this.baseStack = baseStack;
}
BannerPattern_1_13_2(final RegistryKey<BannerPattern> pattern, final String recipe1, final String recipe2, final String recipe3) {
this(pattern);
BannerPattern_1_13_2(String id, String recipe1, String recipe2, String recipe3) {
this(id);
this.recipePattern[0] = recipe1;
this.recipePattern[1] = recipe2;
this.recipePattern[2] = recipe3;
}
public RegistryKey<BannerPattern> getKey() {
return this.pattern;
public String getId() {
return this.id;
}
public boolean isCraftable() {

View File

@ -32,7 +32,6 @@ import net.minecraft.recipe.book.CraftingRecipeCategory;
import net.minecraft.registry.tag.ItemTags;
import net.minecraft.screen.ScreenHandler;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import org.jetbrains.annotations.ApiStatus;
import java.util.ArrayList;
import java.util.List;
@ -704,15 +703,13 @@ public class Recipes1_11_2 {
* @param screenHandler The screen handler
* @param inventory The inventory of the screen handler
*/
@ApiStatus.Internal
public static void setCraftingResultSlot(final int syncId, final ScreenHandler screenHandler, final RecipeInputInventory inventory) {
final var network = MinecraftClient.getInstance().getNetworkHandler();
final var world = MinecraftClient.getInstance().world;
final var craftingRecipeInput = inventory.createRecipeInput();
final var result = network.getRecipeManager()
.getFirstMatch(RecipeType.CRAFTING, craftingRecipeInput, world) // Get the first matching recipe
.map(recipe -> recipe.value().craft(craftingRecipeInput, network.getRegistryManager())) // Craft the recipe to get the result
.getFirstMatch(RecipeType.CRAFTING, inventory, world) // Get the first matching recipe
.map(recipe -> recipe.value().craft(inventory, network.getRegistryManager())) // Craft the recipe to get the result
.orElse(ItemStack.EMPTY); // If there is no recipe, set the result to air
// Update the result slot

View File

@ -17,16 +17,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.fixes.viaversion;
package de.florianmichael.viafabricplus.fixes.tracker;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
public class BedrockJoinGameTracker implements StorableObject {
public class JoinGameDataTracker extends StoredObject {
private long seed;
private String levelId;
private long enchantmentSeed;
public JoinGameDataTracker(UserConnection user) {
super(user);
}
public long getSeed() {
return seed;
}

View File

@ -17,14 +17,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.fixes.viaversion;
package de.florianmichael.viafabricplus.fixes.tracker;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
public class TeleportTracker1_7_6_10 implements StorableObject {
public class TeleportTracker extends StoredObject {
private Boolean onGround = null;
public TeleportTracker(UserConnection user) {
super(user);
}
public Boolean getPending() {
return onGround;
}

View File

@ -17,16 +17,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.fixes.viaversion;
package de.florianmichael.viafabricplus.fixes.tracker;
import com.viaversion.viaversion.api.connection.StorableObject;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
public class WolfHealthTracker1_14_4 implements StorableObject {
public class WolfHealthTracker extends StoredObject {
private final Int2FloatMap healthDataMap = new Int2FloatOpenHashMap();
public WolfHealthTracker(UserConnection user) {
super(user);
}
public float getWolfHealth(final int entityId, final float fallback) {
return this.healthDataMap.getOrDefault(entityId, fallback);
}
@ -35,4 +40,12 @@ public class WolfHealthTracker1_14_4 implements StorableObject {
this.healthDataMap.put(entityId, wolfHealth);
}
public static WolfHealthTracker get(final UserConnection userConnection) {
var tracker = userConnection.get(WolfHealthTracker.class);
if (tracker == null) {
userConnection.put(tracker = new WolfHealthTracker(userConnection));
}
return tracker;
}
}

View File

@ -1,96 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.fixes.versioned;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.tag.BlockTags;
import org.jetbrains.annotations.ApiStatus;
import java.util.Optional;
@ApiStatus.Internal
public class EnchantmentAttributesEmulation1_20_6 {
static {
ClientTickEvents.START_WORLD_TICK.register(world -> {
if (ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_20_5)) {
return;
}
// Update generic attributes for all entities
for (Entity entity : world.getEntities()) {
if (entity.isLogicalSideForUpdatingMovement() && entity instanceof LivingEntity livingEntity) {
livingEntity.getAttributeInstance(EntityAttributes.GENERIC_WATER_MOVEMENT_EFFICIENCY).setBaseValue(getEquipmentLevel(Enchantments.DEPTH_STRIDER, livingEntity) / 3F);
setGenericMovementEfficiencyAttribute(livingEntity);
}
}
// Update player specific attributes for all players
for (PlayerEntity player : world.getPlayers()) {
if (!player.isLogicalSideForUpdatingMovement()) {
continue;
}
final int efficiencyLevel = getEquipmentLevel(Enchantments.EFFICIENCY, player);
if (efficiencyLevel > 0) {
player.getAttributeInstance(EntityAttributes.PLAYER_MINING_EFFICIENCY).setBaseValue(efficiencyLevel * efficiencyLevel + 1);
} else {
player.getAttributeInstance(EntityAttributes.PLAYER_MINING_EFFICIENCY).setBaseValue(0);
}
player.getAttributeInstance(EntityAttributes.PLAYER_SNEAKING_SPEED).setBaseValue(0.3F + getEquipmentLevel(Enchantments.SWIFT_SNEAK, player) * 0.15F);
player.getAttributeInstance(EntityAttributes.PLAYER_SUBMERGED_MINING_SPEED).setBaseValue(getEquipmentLevel(Enchantments.AQUA_AFFINITY, player) <= 0 ? 0.2F : 1F);
}
});
}
public static void init() {
// Calls the static block
}
/**
* Called from MixinLivingEntity as well to ensure the attribute value is set at the correct place in the entity tick logic.
* Called above just as a fallback if a mod accesses the raw attribute value directly.
*/
public static void setGenericMovementEfficiencyAttribute(final LivingEntity entity) {
final boolean isOnSoulSpeedBlock = entity.getWorld().getBlockState(entity.getVelocityAffectingPos()).isIn(BlockTags.SOUL_SPEED_BLOCKS);
if (isOnSoulSpeedBlock && getEquipmentLevel(Enchantments.SOUL_SPEED, entity) > 0) {
entity.getAttributeInstance(EntityAttributes.GENERIC_MOVEMENT_EFFICIENCY).setBaseValue(1);
} else {
entity.getAttributeInstance(EntityAttributes.GENERIC_MOVEMENT_EFFICIENCY).setBaseValue(0);
}
}
private static int getEquipmentLevel(final RegistryKey<Enchantment> enchantment, final LivingEntity entity) {
final Optional<RegistryEntry.Reference<Enchantment>> enchantmentRef = entity.getWorld().getRegistryManager().getWrapperOrThrow(RegistryKeys.ENCHANTMENT).getOptional(enchantment);
return enchantmentRef.map(e -> EnchantmentHelper.getEquipmentLevel(e, entity)).orElse(0);
}
}

View File

@ -1,82 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.fixes.versioned;
import com.viaversion.viaversion.util.Key;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.registry.RegistryKey;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class Enchantments1_14_4 {
private static final Map<String, RegistryKey<Enchantment>> ENCHANTMENT_REGISTRY = new HashMap<>();
static {
ENCHANTMENT_REGISTRY.put("protection", Enchantments.PROTECTION);
ENCHANTMENT_REGISTRY.put("fire_protection", Enchantments.FIRE_PROTECTION);
ENCHANTMENT_REGISTRY.put("feather_falling", Enchantments.FEATHER_FALLING);
ENCHANTMENT_REGISTRY.put("blast_protection", Enchantments.BLAST_PROTECTION);
ENCHANTMENT_REGISTRY.put("projectile_protection", Enchantments.PROJECTILE_PROTECTION);
ENCHANTMENT_REGISTRY.put("respiration", Enchantments.RESPIRATION);
ENCHANTMENT_REGISTRY.put("aqua_affinity", Enchantments.AQUA_AFFINITY);
ENCHANTMENT_REGISTRY.put("thorns", Enchantments.THORNS);
ENCHANTMENT_REGISTRY.put("depth_strider", Enchantments.DEPTH_STRIDER);
ENCHANTMENT_REGISTRY.put("frost_walker", Enchantments.FROST_WALKER);
ENCHANTMENT_REGISTRY.put("binding_curse", Enchantments.BINDING_CURSE);
ENCHANTMENT_REGISTRY.put("sharpness", Enchantments.SHARPNESS);
ENCHANTMENT_REGISTRY.put("smite", Enchantments.SMITE);
ENCHANTMENT_REGISTRY.put("bane_of_arthropods", Enchantments.BANE_OF_ARTHROPODS);
ENCHANTMENT_REGISTRY.put("knockback", Enchantments.KNOCKBACK);
ENCHANTMENT_REGISTRY.put("fire_aspect", Enchantments.FIRE_ASPECT);
ENCHANTMENT_REGISTRY.put("looting", Enchantments.LOOTING);
ENCHANTMENT_REGISTRY.put("sweeping", Enchantments.SWEEPING_EDGE);
ENCHANTMENT_REGISTRY.put("efficiency", Enchantments.EFFICIENCY);
ENCHANTMENT_REGISTRY.put("silk_touch", Enchantments.SILK_TOUCH);
ENCHANTMENT_REGISTRY.put("unbreaking", Enchantments.UNBREAKING);
ENCHANTMENT_REGISTRY.put("fortune", Enchantments.FORTUNE);
ENCHANTMENT_REGISTRY.put("power", Enchantments.POWER);
ENCHANTMENT_REGISTRY.put("punch", Enchantments.PUNCH);
ENCHANTMENT_REGISTRY.put("flame", Enchantments.FLAME);
ENCHANTMENT_REGISTRY.put("infinity", Enchantments.INFINITY);
ENCHANTMENT_REGISTRY.put("luck_of_the_sea", Enchantments.LUCK_OF_THE_SEA);
ENCHANTMENT_REGISTRY.put("lure", Enchantments.LURE);
ENCHANTMENT_REGISTRY.put("loyalty", Enchantments.LOYALTY);
ENCHANTMENT_REGISTRY.put("impaling", Enchantments.IMPALING);
ENCHANTMENT_REGISTRY.put("riptide", Enchantments.RIPTIDE);
ENCHANTMENT_REGISTRY.put("channeling", Enchantments.CHANNELING);
ENCHANTMENT_REGISTRY.put("multishot", Enchantments.MULTISHOT);
ENCHANTMENT_REGISTRY.put("quick_charge", Enchantments.QUICK_CHARGE);
ENCHANTMENT_REGISTRY.put("piercing", Enchantments.PIERCING);
ENCHANTMENT_REGISTRY.put("mending", Enchantments.MENDING);
ENCHANTMENT_REGISTRY.put("vanishing_curse", Enchantments.VANISHING_CURSE);
}
public static Optional<RegistryKey<Enchantment>> getOrEmpty(final String identifier) {
if (identifier == null) {
return Optional.empty();
}
return Optional.ofNullable(ENCHANTMENT_REGISTRY.get(Key.stripMinecraftNamespace(identifier)));
}
}

View File

@ -20,42 +20,28 @@
package de.florianmichael.viafabricplus.fixes.versioned.classic;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import io.netty.buffer.ByteBuf;
import net.lenni0451.reflect.Enums;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialegacy.protocol.classic.c0_30cpetoc0_28_30.data.ClassicProtocolExtension;
import net.raphimc.vialegacy.protocol.classic.c0_30cpetoc0_28_30.packet.ClientboundPacketsc0_30cpe;
import org.jetbrains.annotations.ApiStatus;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.ClientboundPacketsc0_30cpe;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.data.ClassicProtocolExtension;
import java.util.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
public class CPEAdditions {
public final static List<ClassicProtocolExtension> ALLOWED_EXTENSIONS = new ArrayList<>();
public final static List<ClassicProtocolExtension> ALLOWED_EXTENSIONS = Arrays.asList(ClassicProtocolExtension.ENV_WEATHER_TYPE);
public final static Map<Integer, ClientboundPacketsc0_30cpe> CUSTOM_PACKETS = new HashMap<>();
public static ClientboundPacketsc0_30cpe EXT_WEATHER_TYPE;
private static boolean snowing = false;
@ApiStatus.Internal
public static void modifyMappings() {
allowExtension(ClassicProtocolExtension.ENV_WEATHER_TYPE);
EXT_WEATHER_TYPE = createNewPacket(ClassicProtocolExtension.ENV_WEATHER_TYPE, 31, (user, buf) -> buf.readByte());
}
@ApiStatus.Internal
public static boolean isSnowing() {
return ProtocolTranslator.getTargetVersion().equals(LegacyProtocolVersion.c0_30cpe) && snowing;
}
@ApiStatus.Internal
public static void setSnowing(boolean snowing) {
CPEAdditions.snowing = snowing;
}
public static void allowExtension(final ClassicProtocolExtension classicProtocolExtension) {
ALLOWED_EXTENSIONS.add(classicProtocolExtension);
}

View File

@ -90,15 +90,6 @@ public class GridItemSelectionScreen extends VFPScreen {
return super.mouseClicked(mouseX, mouseY, button);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (client.options.inventoryKey.matchesKey(keyCode, scanCode)) {
this.close();
return true;
}
return super.keyPressed(keyCode, scanCode, modifiers);
}
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
final int halfWidth = this.width / 2;

View File

@ -25,20 +25,18 @@ import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.chunk.ChunkType1_17;
import com.viaversion.nbt.tag.CompoundTag;
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialegacy.protocol.classic.c0_28_30toa1_0_15.model.ClassicLevel;
import net.raphimc.vialegacy.protocol.classic.c0_28_30toa1_0_15.provider.ClassicWorldHeightProvider;
import net.raphimc.vialegacy.protocol.classic.c0_28_30toa1_0_15.storage.ClassicLevelStorage;
import org.jetbrains.annotations.ApiStatus;
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.model.ClassicLevel;
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.providers.ClassicWorldHeightProvider;
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.storage.ClassicLevelStorage;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
@ApiStatus.Internal
public class WorldHeightSupport {
public static PacketHandler handleJoinGame(final PacketHandler parentHandler) {
@ -47,10 +45,10 @@ public class WorldHeightSupport {
if (wrapper.isCancelled()) return;
if (wrapper.user().getProtocolInfo().serverProtocolVersion().olderThanOrEqualTo(LegacyProtocolVersion.c0_28toc0_30)) {
for (CompoundTag dimension : wrapper.get(Types.NAMED_COMPOUND_TAG, 0).getCompoundTag("minecraft:dimension_type").getListTag("value", CompoundTag.class)) {
for (CompoundTag dimension : wrapper.get(Type.NAMED_COMPOUND_TAG, 0).getCompoundTag("minecraft:dimension_type").getListTag("value", CompoundTag.class)) {
changeDimensionTagHeight(wrapper.user(), dimension.getCompoundTag("element"));
}
changeDimensionTagHeight(wrapper.user(), wrapper.get(Types.NAMED_COMPOUND_TAG, 1));
changeDimensionTagHeight(wrapper.user(), wrapper.get(Type.NAMED_COMPOUND_TAG, 1));
}
};
}
@ -61,7 +59,7 @@ public class WorldHeightSupport {
if (wrapper.isCancelled()) return;
if (wrapper.user().getProtocolInfo().serverProtocolVersion().olderThanOrEqualTo(LegacyProtocolVersion.c0_28toc0_30)) {
changeDimensionTagHeight(wrapper.user(), wrapper.get(Types.NAMED_COMPOUND_TAG, 0));
changeDimensionTagHeight(wrapper.user(), wrapper.get(Type.NAMED_COMPOUND_TAG, 0));
}
};
}
@ -105,14 +103,14 @@ public class WorldHeightSupport {
final PacketHandler classicLightHandler = new PacketHandlers() {
@Override
public void register() {
map(Types.VAR_INT); // x
map(Types.VAR_INT); // y
map(Types.BOOLEAN); // trust edges
map(Type.VAR_INT); // x
map(Type.VAR_INT); // y
map(Type.BOOLEAN); // trust edges
handler(wrapper -> {
wrapper.read(Types.VAR_INT); // sky light mask
wrapper.read(Types.VAR_INT); // block light mask
final int emptySkyLightMask = wrapper.read(Types.VAR_INT); // empty sky light mask
final int emptyBlockLightMask = wrapper.read(Types.VAR_INT); // empty block light mask
wrapper.read(Type.VAR_INT); // sky light mask
wrapper.read(Type.VAR_INT); // block light mask
final int emptySkyLightMask = wrapper.read(Type.VAR_INT); // empty sky light mask
final int emptyBlockLightMask = wrapper.read(Type.VAR_INT); // empty block light mask
final ClassicLevel level = wrapper.user().get(ClassicLevelStorage.class).getClassicLevel();
final ClassicWorldHeightProvider heightProvider = Via.getManager().getProviders().get(ClassicWorldHeightProvider.class);
@ -124,8 +122,8 @@ public class WorldHeightSupport {
}
final List<byte[]> lightArrays = new ArrayList<>();
while (wrapper.isReadable(Types.BYTE_ARRAY_PRIMITIVE, 0)) {
lightArrays.add(wrapper.read(Types.BYTE_ARRAY_PRIMITIVE));
while (wrapper.isReadable(Type.BYTE_ARRAY_PRIMITIVE, 0)) {
lightArrays.add(wrapper.read(Type.BYTE_ARRAY_PRIMITIVE));
}
int skyLightCount = 16;
@ -143,18 +141,18 @@ public class WorldHeightSupport {
skyLightMask.set(0, skyLightCount);
blockLightMask.set(0, blockLightCount);
wrapper.write(Types.LONG_ARRAY_PRIMITIVE, skyLightMask.toLongArray());
wrapper.write(Types.LONG_ARRAY_PRIMITIVE, blockLightMask.toLongArray());
wrapper.write(Types.LONG_ARRAY_PRIMITIVE, new long[emptySkyLightMask]);
wrapper.write(Types.LONG_ARRAY_PRIMITIVE, new long[emptyBlockLightMask]);
wrapper.write(Type.LONG_ARRAY_PRIMITIVE, skyLightMask.toLongArray());
wrapper.write(Type.LONG_ARRAY_PRIMITIVE, blockLightMask.toLongArray());
wrapper.write(Type.LONG_ARRAY_PRIMITIVE, new long[emptySkyLightMask]);
wrapper.write(Type.LONG_ARRAY_PRIMITIVE, new long[emptyBlockLightMask]);
wrapper.write(Types.VAR_INT, skyLightCount);
wrapper.write(Type.VAR_INT, skyLightCount);
for (int i = 0; i < skyLightCount; i++) {
wrapper.write(Types.BYTE_ARRAY_PRIMITIVE, lightArrays.remove(0));
wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, lightArrays.remove(0));
}
wrapper.write(Types.VAR_INT, blockLightCount);
wrapper.write(Type.VAR_INT, blockLightCount);
for (int i = 0; i < blockLightCount; i++) {
wrapper.write(Types.BYTE_ARRAY_PRIMITIVE, lightArrays.remove(0));
wrapper.write(Type.BYTE_ARRAY_PRIMITIVE, lightArrays.remove(0));
}
});
}

View File

@ -24,9 +24,9 @@ import de.florianmichael.viafabricplus.injection.access.IExtensionProtocolMetada
import de.florianmichael.viafabricplus.protocoltranslator.impl.command.VFPViaSubCommand;
import net.minecraft.util.Formatting;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialegacy.protocol.classic.c0_30cpetoc0_28_30.storage.ExtensionProtocolMetadataStorage;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.storage.ExtensionProtocolMetadataStorage;
public class ListExtensionsCommand implements VFPViaSubCommand {
public class ListExtensionsCommand extends VFPViaSubCommand {
@Override
public String name() {

View File

@ -23,9 +23,9 @@ import com.viaversion.viaversion.api.command.ViaCommandSender;
import de.florianmichael.viafabricplus.protocoltranslator.impl.command.VFPViaSubCommand;
import net.minecraft.util.Formatting;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialegacy.protocol.alpha.a1_0_16_2toa1_0_17_1_0_17_4.storage.TimeLockStorage;
import net.raphimc.vialegacy.protocols.alpha.protocola1_0_17_1_0_17_4toa1_0_16_2.storage.TimeLockStorage;
public class SetTimeCommand implements VFPViaSubCommand {
public class SetTimeCommand extends VFPViaSubCommand {
@Override
public String name() {

View File

@ -21,10 +21,10 @@ package de.florianmichael.viafabricplus.fixes.versioned.visual;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocols.v1_8to1_9.Protocol1_8To1_9;
import com.viaversion.viaversion.protocols.v1_8to1_9.data.ArmorTypes1_8;
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_9;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ArmorType;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
@ -32,19 +32,17 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registries;
import org.jetbrains.annotations.ApiStatus;
import java.util.UUID;
@ApiStatus.Internal
public class ArmorHudEmulation1_8 {
private static final UUID ARMOR_POINTS_UUID = UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150");
private static double previousArmorPoints = 0;
static {
ClientTickEvents.START_WORLD_TICK.register(world -> {
public static void init() {
ClientTickEvents.START_CLIENT_TICK.register(world -> {
if (!VisualSettings.global().emulateArmorHud.isEnabled()) {
return;
}
@ -64,15 +62,11 @@ public class ArmorHudEmulation1_8 {
});
}
public static void init() {
// Calls the static block
}
private static void sendArmorUpdate(final UserConnection userConnection) {
private static void sendArmorUpdate(final UserConnection userConnection) throws Exception {
// Calculate the armor points.
int armor = 0;
for (final ItemStack stack : MinecraftClient.getInstance().player.getInventory().armor) {
armor += ArmorTypes1_8.findByType(Registries.ITEM.getId(stack.getItem()).toString()).getArmorPoints();
armor += ArmorType.findByType(Registries.ITEM.getId(stack.getItem()).toString()).getArmorPoints();
}
// We only want to update the armor points if they actually changed.
@ -81,16 +75,16 @@ public class ArmorHudEmulation1_8 {
}
previousArmorPoints = armor;
final PacketWrapper updateAttributes = PacketWrapper.create(ClientboundPackets1_9.UPDATE_ATTRIBUTES, userConnection);
updateAttributes.write(Types.VAR_INT, MinecraftClient.getInstance().player.getId());
updateAttributes.write(Types.INT, 1);
updateAttributes.write(Types.STRING, "generic.armor");
updateAttributes.write(Types.DOUBLE, 0.0D);
updateAttributes.write(Types.VAR_INT, 1);
updateAttributes.write(Types.UUID, ARMOR_POINTS_UUID);
updateAttributes.write(Types.DOUBLE, (double) armor);
updateAttributes.write(Types.BYTE, (byte) 0);
updateAttributes.scheduleSend(Protocol1_8To1_9.class);
final PacketWrapper entityProperties = PacketWrapper.create(ClientboundPackets1_9.ENTITY_PROPERTIES, userConnection);
entityProperties.write(Type.VAR_INT, MinecraftClient.getInstance().player.getId());
entityProperties.write(Type.INT, 1);
entityProperties.write(Type.STRING, "generic.armor");
entityProperties.write(Type.DOUBLE, 0.0D);
entityProperties.write(Type.VAR_INT, 1);
entityProperties.write(Type.UUID, ARMOR_POINTS_UUID);
entityProperties.write(Type.DOUBLE, (double) armor);
entityProperties.write(Type.BYTE, (byte) 0);
entityProperties.scheduleSend(Protocol1_9To1_8.class);
}
}

View File

@ -31,7 +31,7 @@ import net.minecraft.util.Identifier;
*/
public class BoatModel1_8 extends CompositeEntityModel<BoatEntity> {
public static final EntityModelLayer MODEL_LAYER = new EntityModelLayer(Identifier.of("viafabricplus", "boat1_8"), "main");
public static final EntityModelLayer MODEL_LAYER = new EntityModelLayer(new Identifier("viafabricplus", "boat1_8"), "main");
private final ImmutableList<ModelPart> parts;
public BoatModel1_8(ModelPart root) {

View File

@ -35,7 +35,7 @@ import net.minecraft.util.math.RotationAxis;
*/
public class BoatRenderer1_8 extends EntityRenderer<BoatEntity> {
private static final Identifier TEXTURE = Identifier.of("viafabricplus", "textures/boat1_8.png");
private static final Identifier TEXTURE = new Identifier("viafabricplus", "textures/boat1_8.png");
private final BoatModel1_8 model;
public BoatRenderer1_8(EntityRendererFactory.Context ctx) {
@ -68,7 +68,7 @@ public class BoatRenderer1_8 extends EntityRenderer<BoatEntity> {
matrices.scale(-1, -1, 1);
model.setAngles(entity, tickDelta, 0, -0.1f, 0, 0);
VertexConsumer vertexConsumer = vertexConsumers.getBuffer(model.getLayer(TEXTURE));
model.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV);
model.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1);
matrices.pop();
super.render(entity, yaw, tickDelta, matrices, vertexConsumers, light);

View File

@ -34,7 +34,7 @@ import net.minecraft.entity.vehicle.AbstractMinecartEntity;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.entity.vehicle.ChestBoatEntity;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import org.joml.Vector3f;
/**
* Minecraft 1.20.2 changed the calculation of the mounted height offset for all entities, this class contains the old
@ -49,18 +49,18 @@ public class EntityRidingOffsetsPre1_20_2 {
* @param passenger The passenger of the entity.
* @return The mounted height offset.
*/
public static Vec3d getMountedHeightOffset(final Entity entity, final Entity passenger) {
double yOffset = entity.getHeight() * 0.75F;
public static Vector3f getMountedHeightOffset(final Entity entity, final Entity passenger) {
float yOffset = entity.getHeight() * 0.75F;
if (entity instanceof BoatEntity boatEntity) {
if (!boatEntity.hasPassenger(passenger)) return Vec3d.ZERO;
if (!boatEntity.hasPassenger(passenger)) return new Vector3f();
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
yOffset = -0.3F;
final double xOffset = MathHelper.cos(boatEntity.getYaw() * MathHelper.PI / 180F);
final double zOffset = MathHelper.sin(boatEntity.getYaw() * MathHelper.PI / 180F);
final float xOffset = MathHelper.cos(boatEntity.getYaw() * MathHelper.PI / 180F);
final float zOffset = MathHelper.sin(boatEntity.getYaw() * MathHelper.PI / 180F);
return new Vec3d(0.4F * xOffset, yOffset, 0.4F * zOffset);
return new Vector3f(0.4F * xOffset, yOffset, 0.4F * zOffset);
} else {
if (boatEntity.isRemoved()) {
yOffset = 0.01F;
@ -68,7 +68,7 @@ public class EntityRidingOffsetsPre1_20_2 {
yOffset = boatEntity.getVariant() == BoatEntity.Type.BAMBOO ? 0.25F : -0.1F;
}
double xOffset = boatEntity instanceof ChestBoatEntity ? 0.15F : 0F;
float xOffset = boatEntity instanceof ChestBoatEntity ? 0.15F : 0F;
if (boatEntity.getPassengerList().size() > 1) {
final int idx = boatEntity.getPassengerList().indexOf(passenger);
if (idx == 0) {
@ -80,34 +80,34 @@ public class EntityRidingOffsetsPre1_20_2 {
if (passenger instanceof AnimalEntity) xOffset += 0.2F;
}
return new Vec3d(xOffset, yOffset, 0F).rotateY(-(float) (Math.PI / 2));
return new Vector3f(xOffset, yOffset, 0F);
}
} else if (entity instanceof CamelEntity camelEntity) {
if (!camelEntity.hasPassenger(passenger)) return Vec3d.ZERO;
if (!camelEntity.hasPassenger(passenger)) return new Vector3f();
final boolean firstPassenger = camelEntity.getPassengerList().indexOf(passenger) == 0;
yOffset = camelEntity.getDimensions(camelEntity.isSitting() ? EntityPose.SITTING : EntityPose.STANDING).height() - (camelEntity.isBaby() ? 0.35F : 0.6F);
yOffset = camelEntity.getDimensions(camelEntity.isSitting() ? EntityPose.SITTING : EntityPose.STANDING).height - (camelEntity.isBaby() ? 0.35F : 0.6F);
if (camelEntity.isRemoved()) {
yOffset = 0.01F;
} else {
yOffset = camelEntity.getPassengerAttachmentY(firstPassenger, 0F, EntityDimensions.fixed(0F, (float) ((0.375F * camelEntity.getScaleFactor()) + yOffset)), camelEntity.getScaleFactor());
yOffset = (float) camelEntity.getPassengerAttachmentY(firstPassenger, 0F, EntityDimensions.fixed(0F, (0.375F * camelEntity.getScaleFactor()) + yOffset), camelEntity.getScaleFactor());
}
double zOffset = 0.5F;
float zOffset = 0.5F;
if (camelEntity.getPassengerList().size() > 1) {
if (!firstPassenger) zOffset = -0.7F;
if (passenger instanceof AnimalEntity) zOffset += 0.2F;
}
return new Vec3d(0, yOffset, zOffset);
return new Vector3f(0, yOffset, zOffset);
} else if (entity instanceof ChickenEntity chickenEntity) {
return new Vec3d(0, chickenEntity.getBodyY(0.5D) - chickenEntity.getY(), -0.1F);
return new Vector3f(0, (float) (chickenEntity.getBodyY(0.5D) - chickenEntity.getY()), -0.1F);
} else if (entity instanceof EnderDragonEntity enderDragonEntity) {
yOffset = enderDragonEntity.body.getHeight();
} else if (entity instanceof HoglinEntity hoglinEntity) {
yOffset = hoglinEntity.getHeight() - (hoglinEntity.isBaby() ? 0.2F : 0.15F);
} else if (entity instanceof LlamaEntity) {
return new Vec3d(0, entity.getHeight() * 0.6F, -0.3F);
return new Vector3f(0, entity.getHeight() * 0.6F, -0.3F);
} else if (entity instanceof PhantomEntity) {
yOffset = entity.getStandingEyeHeight();
} else if (entity instanceof PiglinEntity) {
@ -134,11 +134,11 @@ public class EntityRidingOffsetsPre1_20_2 {
if (entity instanceof AbstractHorseEntity abstractHorseEntity) {
if (abstractHorseEntity.lastAngryAnimationProgress > 0.0F) {
return new Vec3d(0, yOffset + 0.15F * abstractHorseEntity.lastAngryAnimationProgress, -0.7F * abstractHorseEntity.lastAngryAnimationProgress);
return new Vector3f(0, yOffset + 0.15F * abstractHorseEntity.lastAngryAnimationProgress, -0.7F * abstractHorseEntity.lastAngryAnimationProgress);
}
}
return new Vec3d(0, yOffset, 0);
return new Vector3f(0, yOffset, 0);
}
/**

View File

@ -27,28 +27,16 @@ import net.minecraft.client.particle.*;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.particle.SimpleParticleType;
import net.minecraft.particle.DefaultParticleType;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
public class FootStepParticle1_12_2 extends SpriteBillboardParticle {
public static final Identifier ID = Identifier.of("viafabricplus", "footstep");
public static int RAW_ID;
static {
final SimpleParticleType footStepType = FabricParticleTypes.simple(true);
Registry.register(Registries.PARTICLE_TYPE, ID, footStepType);
ParticleFactoryRegistry.getInstance().register(footStepType, FootStepParticle1_12_2.Factory::new);
RAW_ID = Registries.PARTICLE_TYPE.getRawId(footStepType);
}
public static int ID;
protected FootStepParticle1_12_2(ClientWorld clientWorld, double x, double y, double z) {
super(clientWorld, x, y, z);
@ -83,17 +71,22 @@ public class FootStepParticle1_12_2 extends SpriteBillboardParticle {
final float maxV = this.getMaxV();
final int light = this.getBrightness(tickDelta); // This is missing in the original code, that's why the particles are broken
vertexConsumer.vertex(x - scale, y, z + scale).texture(maxU, maxV).color(this.red, this.green, this.blue, this.alpha).light(light);
vertexConsumer.vertex(x + scale, y, z + scale).texture(maxU, minV).color(this.red, this.green, this.blue, this.alpha).light(light);
vertexConsumer.vertex(x + scale, y, z - scale).texture(minU, minV).color(this.red, this.green, this.blue, this.alpha).light(light);
vertexConsumer.vertex(x - scale, y, z - scale).texture(minU, maxV).color(this.red, this.green, this.blue, this.alpha).light(light);
vertexConsumer.vertex(x - scale, y, z + scale).texture(maxU, maxV).color(this.red, this.green, this.blue, this.alpha).light(light).next();
vertexConsumer.vertex(x + scale, y, z + scale).texture(maxU, minV).color(this.red, this.green, this.blue, this.alpha).light(light).next();
vertexConsumer.vertex(x + scale, y, z - scale).texture(minU, minV).color(this.red, this.green, this.blue, this.alpha).light(light).next();
vertexConsumer.vertex(x - scale, y, z - scale).texture(minU, maxV).color(this.red, this.green, this.blue, this.alpha).light(light).next();
}
public static void init() {
// Calls the static block
final DefaultParticleType footStepType = FabricParticleTypes.simple(true);
Registry.register(Registries.PARTICLE_TYPE, new Identifier("viafabricplus", "footstep"), footStepType);
ParticleFactoryRegistry.getInstance().register(footStepType, FootStepParticle1_12_2.Factory::new);
ID = Registries.PARTICLE_TYPE.getRawId(footStepType);
}
public static class Factory implements ParticleFactory<SimpleParticleType> {
public static class Factory implements ParticleFactory<DefaultParticleType> {
private final SpriteProvider spriteProvider;
@ -102,7 +95,7 @@ public class FootStepParticle1_12_2 extends SpriteBillboardParticle {
}
@Override
public Particle createParticle(SimpleParticleType parameters, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
public Particle createParticle(DefaultParticleType parameters, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
if (ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_12_2)) {
throw new UnsupportedOperationException("FootStepParticle is not supported on versions newer than 1.12.2");
}

View File

@ -1,73 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.fixes.versioned.visual;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback;
import de.florianmichael.viafabricplus.protocoltranslator.util.LanguageUtil;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.option.SimpleOption;
import net.minecraft.client.resource.language.TranslationStorage;
import net.minecraft.util.Language;
import org.jetbrains.annotations.ApiStatus;
/**
* Older versions only had unicode font support for some languages and therefore servers are expecting the client
* to use a unicode font, not using it on older versions can cause issues with wrong dimensions in chat components.
*/
@ApiStatus.Internal
public class UnicodeFontFix1_12_2 {
private static boolean enabled = false;
private static Runnable task = null;
static {
ChangeProtocolVersionCallback.EVENT.register((oldVersion, newVersion) -> updateUnicodeFontOverride(newVersion));
ClientTickEvents.START_CLIENT_TICK.register(client -> {
// Prevent usages of RenderSystem.recordRenderCall()
if (task != null) {
task.run();
task = null;
}
});
}
public static void init() {
// Calls the static block
}
public static void updateUnicodeFontOverride(final ProtocolVersion version) {
final SimpleOption<Boolean> option = MinecraftClient.getInstance().options.getForceUnicodeFont();
if (VisualSettings.global().forceUnicodeFontForNonAsciiLanguages.isEnabled(version)) {
if (Language.getInstance() instanceof TranslationStorage storage) {
enabled = LanguageUtil.isUnicodeFont1_12_2(storage.translations);
task = () -> option.setValue(enabled);
}
} else if (enabled) {
enabled = false;
task = () -> option.setValue(false);
}
}
}

View File

@ -1,136 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.fixes.viaversion;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.AbstractSimpleProtocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocols.v1_20_3to1_20_5.packet.ServerboundPackets1_20_5;
import com.viaversion.viaversion.protocols.v1_20_5to1_21.packet.ClientboundPackets1_21;
import com.viaversion.viaversion.util.Key;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.network.packet.BrandCustomPayload;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.network.packet.s2c.custom.DebugGameTestAddMarkerCustomPayload;
import net.minecraft.network.packet.s2c.custom.DebugGameTestClearCustomPayload;
import net.minecraft.util.Identifier;
import net.minecraft.util.Pair;
import net.raphimc.viabedrock.api.BedrockProtocolVersion;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import java.util.HashMap;
import java.util.Map;
// Protocol to handle error handling changes in older protocols, always last element of the pipeline
public class ViaFabricPlusProtocol extends AbstractSimpleProtocol {
public static final ViaFabricPlusProtocol INSTANCE = new ViaFabricPlusProtocol();
private final Map<String, Pair<ProtocolVersion, PacketReader>> payloadDiff = new HashMap<>();
public ViaFabricPlusProtocol() {
registerMapping(BrandCustomPayload.ID, LegacyProtocolVersion.c0_0_15a_1, wrapper -> wrapper.passthrough(Types.STRING));
registerMapping(DebugGameTestAddMarkerCustomPayload.ID, ProtocolVersion.v1_14, wrapper -> {
wrapper.passthrough(Types.BLOCK_POSITION1_14);
wrapper.passthrough(Types.INT);
wrapper.passthrough(Types.STRING);
wrapper.passthrough(Types.INT);
});
registerMapping(DebugGameTestClearCustomPayload.ID, ProtocolVersion.v1_14, wrapper -> {
});
}
@Override
protected void registerPackets() {
registerClientbound(State.PLAY, getCustomPayload().getId(), getCustomPayload().getId(), wrapper -> {
final String channel = Key.namespaced(wrapper.passthrough(Types.STRING));
if (!channel.startsWith(Identifier.DEFAULT_NAMESPACE)) {
// Mods might add custom payloads that we don't want to filter, so we check for the namespace.
// Mods should NEVER use the default namespace of the game, not only to not break this code,
// but also to not break other mods and the game itself.
return;
}
final ProtocolVersion version = wrapper.user().getProtocolInfo().serverProtocolVersion();
if (!payloadDiff.containsKey(channel) || version.olderThan(payloadDiff.get(channel).getLeft())) {
// Technically, it's wrong to just drop all payloads. However, ViaVersion doesn't translate them and the server can't detect if
// we handled the payload or not, so dropping them is easier than adding a bunch of useless translations for payloads
// which don't do anything on the client anyway.
wrapper.cancel();
return;
}
if (version.olderThanOrEqualTo(ProtocolVersion.v1_20)) {
// Skip all remaining bytes after reading the payload and cancel if the payload fails to read
final PacketReader reader = payloadDiff.get(channel).getRight();
try {
reader.read(wrapper);
wrapper.read(Types.REMAINING_BYTES);
} catch (Exception ignored) {
wrapper.cancel();
}
}
});
}
@Override
public void init(UserConnection connection) {
super.init(connection);
final ProtocolVersion serverVersion = ProtocolTranslator.getTargetVersion(connection.getChannel());
// Add storages we need for different fixes here
if (serverVersion.equals(BedrockProtocolVersion.bedrockLatest)) {
connection.put(new BedrockJoinGameTracker());
} else {
if (serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_14_4)) {
connection.put(new WolfHealthTracker1_14_4());
}
if (serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_7_6)) {
connection.put(new TeleportTracker1_7_6_10());
}
}
}
private void registerMapping(final CustomPayload.Id<?> id, final ProtocolVersion version, final PacketReader reader) {
payloadDiff.put(id.id().toString(), new Pair<>(version, reader));
}
public static ServerboundPacketType getSetCreativeModeSlot() {
return ServerboundPackets1_20_5.SET_CREATIVE_MODE_SLOT;
}
public static ClientboundPacketType getCustomPayload() {
return ClientboundPackets1_21.CUSTOM_PAYLOAD;
}
@FunctionalInterface
interface PacketReader {
void read(PacketWrapper wrapper);
}
}

View File

@ -19,12 +19,11 @@
package de.florianmichael.viafabricplus.injection.access;
import net.raphimc.vialegacy.protocol.classic.c0_30cpetoc0_28_30.data.ClassicProtocolExtension;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.data.ClassicProtocolExtension;
import java.util.EnumMap;
public interface IExtensionProtocolMetadataStorage {
EnumMap<ClassicProtocolExtension, Integer> viaFabricPlus$getServerExtensions();
}

View File

@ -19,10 +19,12 @@
package de.florianmichael.viafabricplus.injection.access;
import net.minecraft.text.Text;
public interface IItemStack {
public interface IConfirmScreen {
boolean viaFabricPlus$has1_10Tag();
void viaFabricPlus$setMessage(final Text message);
int viaFabricPlus$get1_10Count();
void viaFabricPlus$set1_10Count(final int count);
}

View File

@ -21,7 +21,7 @@ package de.florianmichael.viafabricplus.injection.access;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
public interface IMultiValueDebugSampleLogImpl {
public interface IPerformanceLog {
ProtocolVersion viaFabricPlus$getForcedVersion();
void viaFabricPlus$setForcedVersion(final ProtocolVersion version);

View File

@ -1,26 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.access;
public interface IPlayerListEntry {
int viaFabricPlus$getIndex();
}

View File

@ -1,26 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.access;
public interface IPlayerListHud {
void viaFabricPlus$setMaxPlayers(final int maxPlayers);
}

View File

@ -26,7 +26,7 @@ import com.llamalad7.mixinextras.sugar.Local;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.injection.access.IClientConnection;
import de.florianmichael.viafabricplus.injection.access.IMultiValueDebugSampleLogImpl;
import de.florianmichael.viafabricplus.injection.access.IPerformanceLog;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.protocoltranslator.netty.ViaFabricPlusVLLegacyPipeline;
import io.netty.bootstrap.AbstractBootstrap;
@ -38,9 +38,8 @@ import io.netty.channel.socket.nio.NioDatagramChannel;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.encryption.PacketDecryptor;
import net.minecraft.network.encryption.PacketEncryptor;
import net.minecraft.network.handler.HandlerNames;
import net.minecraft.network.packet.Packet;
import net.minecraft.util.profiler.MultiValueDebugSampleLogImpl;
import net.minecraft.util.profiler.PerformanceLog;
import net.raphimc.viabedrock.api.BedrockProtocolVersion;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialoader.netty.CompressionReorderEvent;
@ -97,7 +96,7 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler<
// Minecraft 1.6.4 supports split encryption/decryption which means the server can only enable one side of the encryption
// So we only enable the encryption side and later enable the decryption side if the 1.7 -> 1.6 protocol
// tells us to do, therefore, we need to store the cipher instance.
// tells us to do, therefore we need to store the cipher instance.
this.viaFabricPlus$decryptionCipher = decryptionCipher;
// Enabling the encryption side
@ -106,7 +105,7 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler<
}
this.encrypted = true;
this.channel.pipeline().addBefore(VLLegacyPipeline.VIALEGACY_PRE_NETTY_LENGTH_REMOVER_NAME, HandlerNames.ENCRYPT, new PacketEncryptor(encryptionCipher));
this.channel.pipeline().addBefore(VLLegacyPipeline.VIALEGACY_PRE_NETTY_LENGTH_REMOVER_NAME, "encrypt", new PacketEncryptor(encryptionCipher));
}
}
@ -123,18 +122,18 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler<
return !BedrockProtocolVersion.bedrockLatest.equals(this.viaFabricPlus$serverVersion);
}
@Inject(method = "connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/util/profiler/MultiValueDebugSampleLogImpl;)Lnet/minecraft/network/ClientConnection;", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/network/ClientConnection;)Lio/netty/channel/ChannelFuture;", shift = At.Shift.BEFORE))
private static void setTargetVersion(InetSocketAddress address, boolean useEpoll, MultiValueDebugSampleLogImpl packetSizeLog, CallbackInfoReturnable<ClientConnection> cir, @Local ClientConnection clientConnection) {
@Inject(method = "connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/util/profiler/PerformanceLog;)Lnet/minecraft/network/ClientConnection;", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/network/ClientConnection;)Lio/netty/channel/ChannelFuture;", shift = At.Shift.BEFORE))
private static void setTargetVersion(InetSocketAddress address, boolean useEpoll, PerformanceLog packetSizeLog, CallbackInfoReturnable<ClientConnection> cir, @Local ClientConnection clientConnection) {
// Set the target version stored in the PerformanceLog field to the ClientConnection instance
if (packetSizeLog instanceof IMultiValueDebugSampleLogImpl mixinMultiValueDebugSampleLogImpl && mixinMultiValueDebugSampleLogImpl.viaFabricPlus$getForcedVersion() != null) {
((IClientConnection) clientConnection).viaFabricPlus$setTargetVersion(mixinMultiValueDebugSampleLogImpl.viaFabricPlus$getForcedVersion());
if (packetSizeLog instanceof IPerformanceLog mixinPerformanceLog && mixinPerformanceLog.viaFabricPlus$getForcedVersion() != null) {
((IClientConnection) clientConnection).viaFabricPlus$setTargetVersion(mixinPerformanceLog.viaFabricPlus$getForcedVersion());
}
}
@WrapWithCondition(method = "connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/util/profiler/MultiValueDebugSampleLogImpl;)Lnet/minecraft/network/ClientConnection;", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;resetPacketSizeLog(Lnet/minecraft/util/profiler/MultiValueDebugSampleLogImpl;)V"))
private static boolean dontSetPerformanceLog(ClientConnection instance, MultiValueDebugSampleLogImpl packetSizeLog) {
@WrapWithCondition(method = "connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/util/profiler/PerformanceLog;)Lnet/minecraft/network/ClientConnection;", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;resetPacketSizeLog(Lnet/minecraft/util/profiler/PerformanceLog;)V"))
private static boolean dontSetPerformanceLog(ClientConnection instance, PerformanceLog log) {
// We need to restore vanilla behaviour since we use the PerformanceLog as a way to store the target version
return !(packetSizeLog instanceof IMultiValueDebugSampleLogImpl mixinMultiValueDebugSampleLogImpl) || mixinMultiValueDebugSampleLogImpl.viaFabricPlus$getForcedVersion() == null;
return !(log instanceof IPerformanceLog mixinPerformanceLog) || mixinPerformanceLog.viaFabricPlus$getForcedVersion() == null;
}
@Inject(method = "connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/network/ClientConnection;)Lio/netty/channel/ChannelFuture;", at = @At("HEAD"))
@ -171,7 +170,7 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler<
new PingEncapsulationCodec(new InetSocketAddress(inetHost, inetPort))
);
f.channel().pipeline().remove(VLPipeline.VIABEDROCK_PACKET_ENCAPSULATION_HANDLER_NAME);
f.channel().pipeline().remove(HandlerNames.SPLITTER);
f.channel().pipeline().remove("splitter");
}
});
} else {
@ -187,7 +186,7 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler<
this.encrypted = true;
// Enabling the decryption side for 1.6.4 if the 1.7 -> 1.6 protocol tells us to do
this.channel.pipeline().addBefore(VLLegacyPipeline.VIALEGACY_PRE_NETTY_LENGTH_PREPENDER_NAME, HandlerNames.DECRYPT, new PacketDecryptor(this.viaFabricPlus$decryptionCipher));
this.channel.pipeline().addBefore(VLLegacyPipeline.VIALEGACY_PRE_NETTY_LENGTH_PREPENDER_NAME, "decrypt", new PacketDecryptor(this.viaFabricPlus$decryptionCipher));
}
@Override

View File

@ -24,7 +24,7 @@ import net.minecraft.client.network.ClientLoginNetworkHandler;
import net.minecraft.network.ClientConnection;
import net.minecraft.text.Text;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialegacy.protocol.release.r1_6_4tor1_7_2_5.storage.ProtocolMetadataStorage;
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.storage.ProtocolMetadataStorage;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;

View File

@ -1,46 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.base.connect;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import net.minecraft.client.option.GameOptions;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(GameOptions.class)
public abstract class MixinGameOptions {
@Shadow
public boolean useNativeTransport;
/**
* @author RK_01
* @reason Needed as an indicator if the client wants to ping a server or connect to a server
*/
@Overwrite
public boolean shouldUseNativeTransport() {
if (!this.useNativeTransport) {
ViaFabricPlus.global().getLogger().error("Native transport is disabled, but enabling it anyway since we use it as an indicator if the client wants to ping a server or connect to a server.");
}
return true;
}
}

View File

@ -78,7 +78,7 @@ public abstract class MixinAddServerScreen extends Screen {
viaFabricPlus$addressField = null;
}
ButtonWidget.Builder buttonBuilder = ButtonWidget.builder(forcedVersion == null ? Text.translatable("base.viafabricplus.set_version") : Text.of(forcedVersion.getName()), button -> {
ButtonWidget.Builder buttonBuilder = ButtonWidget.builder(forcedVersion == null ? Text.translatable("base.viafabricplus.set_version") : Text.literal(forcedVersion.getName()), button -> {
// Store current input in case the user cancels the version selection
viaFabricPlus$nameField = serverNameField.getText();
viaFabricPlus$addressField = addressField.getText();

View File

@ -1,48 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.base.integration;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import io.netty.channel.ChannelHandlerContext;
import net.minecraft.network.ClientConnection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.net.ConnectException;
import java.net.SocketException;
@Mixin(ClientConnection.class)
public abstract class MixinClientConnection {
@Inject(method = "exceptionCaught", at = @At("HEAD"))
private void printNetworkingErrors(ChannelHandlerContext context, Throwable ex, CallbackInfo ci) {
if (DebugSettings.global().printNetworkingErrorsToLogs.getValue()) {
if (ex instanceof SocketException || ex instanceof ConnectException) {
// Thrown when server is not reachable
return;
}
ViaFabricPlus.global().getLogger().error("An exception occurred while handling a packet", ex);
}
}
}

View File

@ -1,59 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.base.integration;
import de.florianmichael.viafabricplus.injection.access.IConfirmScreen;
import net.minecraft.client.gui.screen.ConfirmScreen;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ConfirmScreen.class)
public abstract class MixinConfirmScreen implements IConfirmScreen {
@Mutable
@Shadow
@Final
private Text message;
@Shadow
protected abstract void init();
@Unique
private boolean viaFabricPlus$selfInflicted = false;
@Inject(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/MathHelper;clamp(III)I", shift = At.Shift.AFTER), cancellable = true)
private void preventButtonClearing(CallbackInfo ci) {
if (viaFabricPlus$selfInflicted) {
viaFabricPlus$selfInflicted = false;
ci.cancel();
}
}
@Override
public void viaFabricPlus$setMessage(Text message) {
viaFabricPlus$selfInflicted = true;
this.message = message;
this.init();
}
}

View File

@ -72,7 +72,7 @@ public abstract class MixinConnectScreen_1 {
}
ProtocolTranslator.setTargetVersion(targetVersion, true);
this.viaFabricPlus$useClassiCubeAccount = AuthenticationSettings.global().setSessionNameToClassiCubeNameInServerList.getValue() && ViaFabricPlusClassicMPPassProvider.classicubeMPPass != null;
this.viaFabricPlus$useClassiCubeAccount = AuthenticationSettings.global().setSessionNameToClassiCubeNameInServerList.getValue() && ViaFabricPlusClassicMPPassProvider.classicMpPassForNextJoin != null;
final ChannelFuture future = original.call(address, useEpoll, connection);
ProtocolTranslator.injectPreviousVersionReset(future.channel());

View File

@ -21,7 +21,7 @@ package de.florianmichael.viafabricplus.injection.mixin.base.integration;
import com.viaversion.viaversion.api.connection.ProtocolInfo;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viafabricplus.fixes.viaversion.BedrockJoinGameTracker;
import de.florianmichael.viafabricplus.fixes.tracker.JoinGameDataTracker;
import de.florianmichael.viafabricplus.injection.ViaFabricPlusMixinPlugin;
import de.florianmichael.viafabricplus.injection.access.IChunkTracker;
import de.florianmichael.viafabricplus.injection.access.IRakSessionCodec;
@ -34,10 +34,9 @@ import net.minecraft.util.Formatting;
import net.raphimc.viabedrock.protocol.data.enums.bedrock.ServerAuthMovementMode;
import net.raphimc.viabedrock.protocol.storage.ChunkTracker;
import net.raphimc.viabedrock.protocol.storage.GameSessionStorage;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialegacy.protocol.classic.c0_30cpetoc0_28_30.storage.ExtensionProtocolMetadataStorage;
import net.raphimc.vialegacy.protocol.release.r1_1tor1_2_1_3.storage.SeedStorage;
import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.storage.EntityTracker;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.storage.ExtensionProtocolMetadataStorage;
import net.raphimc.vialegacy.protocols.release.protocol1_2_1_3to1_1.storage.SeedStorage;
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.storage.EntityTracker;
import org.cloudburstmc.netty.channel.raknet.RakClientChannel;
import org.cloudburstmc.netty.handler.codec.raknet.common.RakSessionCodec;
import org.spongepowered.asm.mixin.Mixin;
@ -83,7 +82,7 @@ public abstract class MixinDebugHud {
// 1.1
final SeedStorage seedStorage = userConnection.get(SeedStorage.class);
if (seedStorage != null && userConnection.getProtocolInfo().serverProtocolVersion().newerThanOrEqualTo(LegacyProtocolVersion.a1_2_0toa1_2_1_1)) {
if (seedStorage != null) {
information.add("World Seed: " + seedStorage.seed);
}
@ -94,7 +93,7 @@ public abstract class MixinDebugHud {
}
// Bedrock
final BedrockJoinGameTracker joinGameDataTracker = userConnection.get(BedrockJoinGameTracker.class);
final JoinGameDataTracker joinGameDataTracker = userConnection.get(JoinGameDataTracker.class);
if (joinGameDataTracker != null) {
final ServerAuthMovementMode movementMode = userConnection.get(GameSessionStorage.class).getMovementMode();
information.add("Bedrock Level: " + joinGameDataTracker.getLevelId() + ", Enchantment Seed: " + joinGameDataTracker.getEnchantmentSeed() + ", Movement: " + movementMode.name());

View File

@ -43,7 +43,7 @@ public abstract class MixinDirectConnectScreen extends Screen {
if (buttonPosition == 0) { // Off
return;
}
ButtonWidget.Builder builder = ButtonWidget.builder(Text.of("ViaFabricPlus"), button -> ProtocolSelectionScreen.INSTANCE.open(this)).size(98, 20);
ButtonWidget.Builder builder = ButtonWidget.builder(Text.literal("ViaFabricPlus"), button -> ProtocolSelectionScreen.INSTANCE.open(this)).size(98, 20);
// Set the button's position according to the configured orientation and add the button to the screen
this.addDrawableChild(GeneralSettings.withOrientation(builder, buttonPosition, width, height).build());

View File

@ -27,7 +27,7 @@ import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.DownloadingTerrainScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
import net.raphimc.vialegacy.protocol.classic.c0_28_30toa1_0_15.storage.ClassicProgressStorage;
import net.raphimc.vialegacy.protocols.classic.protocola1_0_15toc0_28_30.storage.ClassicProgressStorage;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;

View File

@ -19,10 +19,7 @@
package de.florianmichael.viafabricplus.injection.mixin.base.integration;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import de.florianmichael.viafabricplus.injection.access.IServerInfo;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
@ -37,6 +34,7 @@ import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MultiplayerScreen.class)
@ -52,23 +50,21 @@ public abstract class MixinMultiplayerScreen extends Screen {
if (buttonPosition == 0) { // Off
return;
}
ButtonWidget.Builder builder = ButtonWidget.builder(Text.of("ViaFabricPlus"), button -> ProtocolSelectionScreen.INSTANCE.open(this)).size(98, 20);
ButtonWidget.Builder builder = ButtonWidget.builder(Text.literal("ViaFabricPlus"), button -> ProtocolSelectionScreen.INSTANCE.open(this)).size(98, 20);
// Set the button's position according to the configured orientation and add the button to the screen
this.addDrawableChild(GeneralSettings.withOrientation(builder, buttonPosition, width, height).build());
}
@WrapOperation(method = "connect(Lnet/minecraft/client/network/ServerInfo;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;parse(Ljava/lang/String;)Lnet/minecraft/client/network/ServerAddress;"))
private ServerAddress replaceDefaultPort(String address, Operation<ServerAddress> original, @Local(argsOnly = true) ServerInfo entry) {
final IServerInfo mixinServerInfo = (IServerInfo) entry;
ProtocolVersion version;
if (mixinServerInfo.viaFabricPlus$passedDirectConnectScreen()) {
version = ProtocolTranslator.getTargetVersion();
@Redirect(method = "connect(Lnet/minecraft/client/network/ServerInfo;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;parse(Ljava/lang/String;)Lnet/minecraft/client/network/ServerAddress;"))
private ServerAddress replaceDefaultPort(String address, @Local(argsOnly = true) ServerInfo entry) {
if (((IServerInfo) entry).viaFabricPlus$passedDirectConnectScreen()) {
// If the user has already passed the direct connect screen, we use the target version
return ClientsideFixes.replaceDefaultPort(address, ProtocolTranslator.getTargetVersion());
} else {
version = mixinServerInfo.viaFabricPlus$forcedVersion();
// Otherwise the forced version is used
return ClientsideFixes.replaceDefaultPort(address, ((IServerInfo) entry).viaFabricPlus$forcedVersion());
}
return original.call(ClientsideFixes.replaceDefaultPort(address, version));
}
}

View File

@ -27,6 +27,8 @@ import net.minecraft.client.network.ServerInfo;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.listener.ClientQueryPacketListener;
import net.minecraft.network.packet.s2c.query.QueryResponseS2CPacket;
import net.raphimc.viabedrock.api.BedrockProtocolVersion;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;

View File

@ -19,8 +19,9 @@
package de.florianmichael.viafabricplus.injection.mixin.base.integration;
import com.google.common.collect.Lists;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.injection.access.IServerInfo;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
@ -52,6 +53,9 @@ public abstract class MixinMultiplayerServerListWidget_ServerEntry {
@Final
private ServerInfo server;
@Shadow
protected abstract boolean protocolVersionMatches();
@Mutable
@Shadow
@Final
@ -72,12 +76,12 @@ public abstract class MixinMultiplayerServerListWidget_ServerEntry {
return !viaFabricPlus$disableServerPinging;
}
@Redirect(method = "render", at = @At(value = "FIELD", target = "Lnet/minecraft/client/network/ServerInfo$Status;INCOMPATIBLE:Lnet/minecraft/client/network/ServerInfo$Status;"))
private ServerInfo.Status disableServerPinging() {
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerServerListWidget$ServerEntry;protocolVersionMatches()Z"))
private boolean disableServerPinging(MultiplayerServerListWidget.ServerEntry instance) {
if (viaFabricPlus$disableServerPinging) {
return this.server.getStatus(); // server version will always be shown (as we don't have a player count anyway)
return false; // server version will always been shown (as we don't have a player count anyway)
} else {
return ServerInfo.Status.INCOMPATIBLE;
return protocolVersionMatches();
}
}
@ -103,9 +107,9 @@ public abstract class MixinMultiplayerServerListWidget_ServerEntry {
return !viaFabricPlus$disableServerPinging; // Remove ping bar
}
@WrapWithCondition(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;setTooltip(Ljava/util/List;)V"))
@WrapWithCondition(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;setMultiplayerScreenTooltip(Ljava/util/List;)V", ordinal = 1))
private boolean disableServerPinging(MultiplayerScreen instance, List<Text> tooltip) {
return !viaFabricPlus$disableServerPinging; // Remove player list tooltip
return !viaFabricPlus$disableServerPinging; // Remove ping bar tooltip
}
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/world/WorldIcon;getTextureId()Lnet/minecraft/util/Identifier;"))
@ -117,21 +121,20 @@ public abstract class MixinMultiplayerServerListWidget_ServerEntry {
}
}
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;setTooltip(Lnet/minecraft/text/Text;)V"))
private void drawTranslatingState(MultiplayerScreen instance, Text text) {
if (viaFabricPlus$disableServerPinging) { // Remove ping bar tooltip
@WrapOperation(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;setMultiplayerScreenTooltip(Ljava/util/List;)V", ordinal = 0))
private void drawTranslatingState(MultiplayerScreen instance, List<Text> tooltip, Operation<Void> original) {
if (viaFabricPlus$disableServerPinging) { // Remove player list tooltip
return;
}
final List<Text> tooltips = new ArrayList<>();
tooltips.add(text);
final List<Text> tooltipCopy = new ArrayList<>(tooltip);
if (GeneralSettings.global().showAdvertisedServerVersion.getValue()) {
final ProtocolVersion version = ((IServerInfo) server).viaFabricPlus$translatingVersion();
if (version != null) {
tooltips.add(Text.translatable("base.viafabricplus.via_translates_to", version.getName() + " (" + version.getOriginalVersion() + ")"));
tooltips.add(Text.translatable("base.viafabricplus.server_version", server.version.getString() + " (" + server.protocolVersion + ")"));
tooltipCopy.add(Text.translatable("base.viafabricplus.via_translates_to", version.getName() + " (" + version.getOriginalVersion() + ")"));
tooltipCopy.add(Text.translatable("base.viafabricplus.server_version", server.version.getString() + " (" + server.protocolVersion + ")"));
}
}
instance.setTooltip(Lists.transform(tooltips, Text::asOrderedText));
original.call(instance, tooltipCopy);
}
}

View File

@ -19,33 +19,33 @@
package de.florianmichael.viafabricplus.injection.mixin.base.perserverversion;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import de.florianmichael.viafabricplus.injection.access.IMultiValueDebugSampleLogImpl;
import de.florianmichael.viafabricplus.injection.access.IPerformanceLog;
import de.florianmichael.viafabricplus.injection.access.IServerInfo;
import net.minecraft.client.network.MultiplayerServerListPinger;
import net.minecraft.client.network.ServerAddress;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.network.ClientConnection;
import net.minecraft.util.profiler.MultiValueDebugSampleLogImpl;
import net.minecraft.util.profiler.PerformanceLog;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.net.InetSocketAddress;
@Mixin(MultiplayerServerListPinger.class)
public abstract class MixinMultiplayerServerListPinger {
@WrapOperation(method = "add", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;parse(Ljava/lang/String;)Lnet/minecraft/client/network/ServerAddress;"))
private ServerAddress replaceDefaultPort(String address, Operation<ServerAddress> original, @Local(argsOnly = true) ServerInfo entry) {
@Redirect(method = "add", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;parse(Ljava/lang/String;)Lnet/minecraft/client/network/ServerAddress;"))
private ServerAddress replaceDefaultPort(String address, @Local(argsOnly = true) ServerInfo entry) {
// Replace port when pinging the server and the forced version is set
return original.call(ClientsideFixes.replaceDefaultPort(address, ((IServerInfo) entry).viaFabricPlus$forcedVersion()));
return ClientsideFixes.replaceDefaultPort(address, ((IServerInfo) entry).viaFabricPlus$forcedVersion());
}
@WrapOperation(method = "add", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/util/profiler/MultiValueDebugSampleLogImpl;)Lnet/minecraft/network/ClientConnection;"))
private ClientConnection setForcedVersion(InetSocketAddress address, boolean useEpoll, MultiValueDebugSampleLogImpl packetSizeLog, Operation<ClientConnection> original, @Local(argsOnly = true) ServerInfo serverInfo) {
@Redirect(method = "add", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/util/profiler/PerformanceLog;)Lnet/minecraft/network/ClientConnection;"))
private ClientConnection setForcedVersion(InetSocketAddress address, boolean useEpoll, PerformanceLog packetSizeLog, @Local(argsOnly = true) ServerInfo serverInfo) {
final IServerInfo mixinServerInfo = (IServerInfo) serverInfo;
if (mixinServerInfo.viaFabricPlus$forcedVersion() != null && !mixinServerInfo.viaFabricPlus$passedDirectConnectScreen()) {
@ -53,15 +53,15 @@ public abstract class MixinMultiplayerServerListPinger {
// So we can create a dummy instance, store the forced version in it and later destroy the instance again
// To avoid any side effects, we also support cases where a mod is also creating a PerformanceLog instance
if (packetSizeLog == null) {
packetSizeLog = new MultiValueDebugSampleLogImpl(1);
packetSizeLog = new PerformanceLog();
}
// Attach the forced version to the PerformanceLog instance
((IMultiValueDebugSampleLogImpl) packetSizeLog).viaFabricPlus$setForcedVersion(mixinServerInfo.viaFabricPlus$forcedVersion());
((IPerformanceLog) packetSizeLog).viaFabricPlus$setForcedVersion(mixinServerInfo.viaFabricPlus$forcedVersion());
mixinServerInfo.viaFabricPlus$passDirectConnectScreen(false);
}
return original.call(address, useEpoll, packetSizeLog);
return ClientConnection.connect(address, useEpoll, packetSizeLog);
}
}

View File

@ -20,13 +20,13 @@
package de.florianmichael.viafabricplus.injection.mixin.base.perserverversion;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.injection.access.IMultiValueDebugSampleLogImpl;
import net.minecraft.util.profiler.MultiValueDebugSampleLogImpl;
import de.florianmichael.viafabricplus.injection.access.IPerformanceLog;
import net.minecraft.util.profiler.PerformanceLog;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@Mixin(MultiValueDebugSampleLogImpl.class)
public abstract class MixinMultiValueDebugSampleLogImpl implements IMultiValueDebugSampleLogImpl {
@Mixin(PerformanceLog.class)
public abstract class MixinPerformanceLog implements IPerformanceLog {
@Unique
private ProtocolVersion viaFabricPlus$forcedVersion;

View File

@ -19,10 +19,8 @@
package de.florianmichael.viafabricplus.injection.mixin.base.perserverversion;
import com.llamalad7.mixinextras.sugar.Local;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.injection.access.IServerInfo;
import de.florianmichael.viafabricplus.save.impl.SettingsSave;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.nbt.NbtCompound;
import org.spongepowered.asm.mixin.Mixin;
@ -49,17 +47,17 @@ public abstract class MixinServerInfo implements IServerInfo {
@Unique
private ProtocolVersion viaFabricPlus$translatingVersion;
@Inject(method = "toNbt", at = @At("TAIL"))
private void saveForcedVersion(CallbackInfoReturnable<NbtCompound> cir, @Local NbtCompound nbtCompound) {
@Inject(method = "toNbt", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILHARD)
private void saveForcedVersion(CallbackInfoReturnable<NbtCompound> cir, NbtCompound nbtCompound) {
if (viaFabricPlus$forcedVersion != null) {
nbtCompound.putString("viafabricplus_forcedversion", viaFabricPlus$forcedVersion.getName());
}
}
@Inject(method = "fromNbt", at = @At("TAIL"))
private static void loadForcedVersion(NbtCompound root, CallbackInfoReturnable<ServerInfo> cir, @Local ServerInfo serverInfo) {
@Inject(method = "fromNbt", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILHARD)
private static void loadForcedVersion(NbtCompound root, CallbackInfoReturnable<ServerInfo> cir, ServerInfo serverInfo) {
if (root.contains("viafabricplus_forcedversion")) {
final ProtocolVersion version = SettingsSave.protocolVersionByName(root.getString("viafabricplus_forcedversion"));
final ProtocolVersion version = ProtocolVersion.getClosest(root.getString("viafabricplus_forcedversion"));
if (version != null) {
((IServerInfo) serverInfo).viaFabricPlus$forceVersion(version);
}

View File

@ -20,8 +20,8 @@
package de.florianmichael.viafabricplus.injection.mixin.compat.classic4j;
import de.florianmichael.viafabricplus.injection.access.ITextFieldWidget;
import net.minecraft.SharedConstants;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.util.StringHelper;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
@ -37,17 +37,17 @@ public abstract class MixinTextFieldWidget implements ITextFieldWidget {
@Unique
private boolean viaFabricPlus$forbiddenCharactersUnlocked = false;
@Redirect(method = "charTyped", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/StringHelper;isValidChar(C)Z"))
@Redirect(method = "charTyped", at = @At(value = "INVOKE", target = "Lnet/minecraft/SharedConstants;isValidChar(C)Z"))
private boolean allowForbiddenCharacters(char c) {
return this.viaFabricPlus$forbiddenCharactersUnlocked || StringHelper.isValidChar(c);
return this.viaFabricPlus$forbiddenCharactersUnlocked || SharedConstants.isValidChar(c);
}
@Redirect(method = "write", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/StringHelper;stripInvalidChars(Ljava/lang/String;)Ljava/lang/String;"))
@Redirect(method = "write", at = @At(value = "INVOKE", target = "Lnet/minecraft/SharedConstants;stripInvalidChars(Ljava/lang/String;)Ljava/lang/String;"))
private String allowForbiddenCharacters(String string) {
if (this.viaFabricPlus$forbiddenCharactersUnlocked) {
return string;
} else {
return StringHelper.stripInvalidChars(string);
return SharedConstants.stripInvalidChars(string);
}
}

View File

@ -1,59 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.compat.fabricapi;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.fixes.versioned.visual.FootStepParticle1_12_2;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.fabricmc.fabric.impl.registry.sync.RegistrySyncManager;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Map;
@Mixin(RegistrySyncManager.class)
public abstract class MixinRegistrySyncManager {
@WrapOperation(method = "createAndPopulateRegistryMap", at = @At(value = "INVOKE", target = "Lnet/minecraft/registry/Registry;getId(Ljava/lang/Object;)Lnet/minecraft/util/Identifier;"), require = 0)
private static Identifier skipFootStepParticle(Registry instance, Object t, Operation<Identifier> original) {
final Identifier id = original.call(instance, t);
if (id == FootStepParticle1_12_2.ID) {
return null;
} else {
return id;
}
}
@Inject(method = "checkRemoteRemap", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;error(Ljava/lang/String;)V", ordinal = 0), cancellable = true, remap = false)
private static void ignoreFabricSyncErrors(Map<Identifier, Object2IntMap<Identifier>> map, CallbackInfo ci) {
if (DebugSettings.global().ignoreFabricSyncErrors.getValue()) {
ViaFabricPlus.global().getLogger().warn("Ignoring missing registries from Fabric API");
ci.cancel();
}
}
}

View File

@ -34,7 +34,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
*
* Fixes https://github.com/ViaVersion/ViaFabricPlus/issues/209
*/
@SuppressWarnings("UnresolvedMixinReference")
@Pseudo
@Mixin(targets = "org.anti_ad.mc.ipnext.event.AutoRefillHandler$ItemSlotMonitor", remap = false)
public abstract class MixinAutoRefillHandler_ItemSlotMonitor {

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.compat.minecraftauth;
package de.florianmichael.viafabricplus.injection.mixin.compat.jsonwebtoken;
import io.jsonwebtoken.lang.Classes;
import org.spongepowered.asm.mixin.Mixin;
@ -26,7 +26,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
/*
* JsonWebToken is used by MinecraftAuth, and since it's using Java services, it's not working with the fabric loader,
* JsonWebToken is used by MinecraftAuth and since it's using Java services, it's not working with the fabric loader
* So we have to change all services usages by using the normal Java API
*/
@Mixin(value = Classes.class, remap = false)

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.compat.minecraftauth;
package de.florianmichael.viafabricplus.injection.mixin.compat.jsonwebtoken;
import io.jsonwebtoken.gson.io.GsonDeserializer;
import io.jsonwebtoken.impl.DefaultJwtParserBuilder;
@ -26,7 +26,7 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
/*
* JsonWebToken is used by MinecraftAuth, and since it's using Java services, it's not working with the fabric loader,
* JsonWebToken is used by MinecraftAuth and since it's using Java services, it's not working with the fabric loader
* So we have to change all services usages by using the normal Java API
*/
@Mixin(value = DefaultJwtParserBuilder.class, remap = false)

View File

@ -27,12 +27,12 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
// Lithium is overriding the sorting with an optimized implementation
// https://github.com/CaffeineMC/lithium-fabric/blob/develop/src/main/java/me/jellysquid/mods/lithium/mixin/entity/collisions/movement/EntityMixin.java#L84
// https://github.com/CaffeineMC/lithium-fabric/blob/develop/src/main/java/me/jellysquid/mods/lithium/mixin/entity/collisions/movement/EntityMixin.java#L54
@Mixin(value = Entity.class, priority = 1001 /* Lithium has to be applied first */)
public abstract class MixinEntity {
@SuppressWarnings({"MixinAnnotationTarget", "UnresolvedMixinReference"})
@Redirect(method = "lithium$CollideMovement", at = @At(value = "INVOKE", target = "Ljava/lang/Math;abs(D)D", ordinal = 0), remap = false)
@Redirect(method = "lithiumCollideMultiAxisMovement", at = @At(value = "INVOKE", target = "Ljava/lang/Math;abs(D)D", ordinal = 0), remap = false)
private static double alwaysSortYXZ(double a) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_13_2)) {
return Double.MAX_VALUE;

View File

@ -19,9 +19,11 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import net.minecraft.client.render.Camera;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.world.BlockView;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@ -37,14 +39,38 @@ public abstract class MixinCamera {
@Shadow
private float lastCameraY;
@Shadow private Entity focusedEntity;
@Shadow
private Entity focusedEntity;
@Inject(method = "updateEyeHeight", at = @At(value = "HEAD"), cancellable = true)
private void sneakInstantly(CallbackInfo ci) {
if (this.focusedEntity != null && VisualSettings.global().sneakInstantly.isEnabled()) {
ci.cancel();
@Inject(method = "update", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/Camera;setPos(DDD)V", shift = At.Shift.BEFORE))
private void onUpdateHeight(BlockView area, Entity focusedEntity, boolean thirdPerson, boolean inverseView, float tickDelta, CallbackInfo ci) {
if (!DebugSettings.global().replaceSneaking.isEnabled() && DebugSettings.global().sneakInstantly.isEnabled()) {
cameraY = lastCameraY = focusedEntity.getStandingEyeHeight();
}
}
@Inject(method = "updateEyeHeight", at = @At(value = "HEAD"), cancellable = true)
private void onUpdateEyeHeight(CallbackInfo ci) {
if (this.focusedEntity == null) return;
if (DebugSettings.global().replaceSneaking.isEnabled()) {
ci.cancel();
this.lastCameraY = this.cameraY;
if (this.focusedEntity instanceof PlayerEntity player && !player.isSleeping()) {
if (player.isSneaking()) {
cameraY = 1.54F;
} else if (!DebugSettings.global().longSneaking.isEnabled()) {
cameraY = 1.62F;
} else if (cameraY < 1.62F) {
float delta = 1.62F - cameraY;
delta *= 0.4F;
cameraY = 1.62F - delta;
}
} else {
cameraY = focusedEntity.getStandingEyeHeight();
}
}
}
}

View File

@ -19,7 +19,8 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ChatInputSuggestor;
import net.minecraft.client.gui.widget.TextFieldWidget;
@ -88,7 +89,7 @@ public abstract class MixinChatInputSuggestor {
@Unique
private boolean viaFabricPlus$cancelTabComplete() {
return DebugSettings.global().legacyTabCompletions.isEnabled() && this.textField.getText().startsWith("/");
return ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_12_2) && this.textField.getText().startsWith("/");
}
}

View File

@ -17,28 +17,33 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.FishingRodItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.world.World;
import net.minecraft.enchantment.EnchantmentHelper;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
@Mixin(FishingRodItem.class)
public abstract class MixinFishingRodItem {
@Mixin(EnchantmentHelper.class)
public abstract class MixinEnchantmentHelper {
@Inject(method = "use", at = @At("RETURN"))
private void swingHand(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable<TypedActionResult<ItemStack>> cir) {
@ModifyConstant(method = "getLevelFromNbt", constant = @Constant(intValue = 0))
private static int usePossibleMinLevel(int constant) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_14_4)) {
user.swingHand(hand);
return Short.MIN_VALUE;
} else {
return constant;
}
}
@ModifyConstant(method = "getLevelFromNbt", constant = @Constant(intValue = 255))
private static int usePossibleMaxLevel(int constant) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_14_4)) {
return Short.MAX_VALUE;
} else {
return constant;
}
}

View File

@ -20,8 +20,8 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.fixes.data.Material1_19_4;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.protocoltranslator.impl.ViaFabricPlusMappingDataLoader;
import net.minecraft.block.*;
import net.minecraft.fluid.FlowableFluid;
import net.minecraft.util.math.BlockPos;
@ -37,8 +37,7 @@ public abstract class MixinFlowableFluid {
@Redirect(method = "isFlowBlocked", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;isSideSolidFullSquare(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)Z"))
private boolean modifyIsSolidBlock(BlockState instance, BlockView blockView, BlockPos blockPos, Direction direction) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_11_1)) {
final ViaFabricPlusMappingDataLoader.Material material = ViaFabricPlusMappingDataLoader.MATERIALS.get(ViaFabricPlusMappingDataLoader.getBlockMaterial(instance.getBlock()));
return material.solid();
return Material1_19_4.getMaterial(instance).solid();
} else if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_13_2)) {
final Block block = instance.getBlock();
if (block instanceof ShulkerBoxBlock || block instanceof LeavesBlock || block instanceof TrapdoorBlock ||

View File

@ -19,6 +19,7 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import com.llamalad7.mixinextras.sugar.Local;
import de.florianmichael.viafabricplus.fixes.data.RenderableGlyphDiff;
import de.florianmichael.viafabricplus.fixes.versioned.visual.BuiltinEmptyGlyph1_12_2;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
@ -35,6 +36,8 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@Mixin(FontStorage.class)
public abstract class MixinFontStorage {
@ -51,20 +54,20 @@ public abstract class MixinFontStorage {
@Unique
private GlyphRenderer viaFabricPlus$blankGlyphRenderer1_12_2;
@Inject(method = "clear", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/BuiltinEmptyGlyph;bake(Ljava/util/function/Function;)Lnet/minecraft/client/font/GlyphRenderer;", ordinal = 0))
private void bakeBlankGlyph1_12_2(CallbackInfo ci) {
@Inject(method = "setFonts", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/BuiltinEmptyGlyph;bake(Ljava/util/function/Function;)Lnet/minecraft/client/font/GlyphRenderer;", ordinal = 0))
private void bakeBlankGlyph1_12_2(List<Font> fonts, CallbackInfo ci) {
this.viaFabricPlus$blankGlyphRenderer1_12_2 = BuiltinEmptyGlyph1_12_2.INSTANCE.bake(this::getGlyphRenderer);
}
@Inject(method = "findGlyph", at = @At("RETURN"), cancellable = true)
private void filterGlyphs(int codePoint, CallbackInfoReturnable<FontStorage.GlyphPair> cir) {
private void filterGlyphs1(int codePoint, CallbackInfoReturnable<FontStorage.GlyphPair> cir, @Local Font font) {
if (this.viaFabricPlus$shouldBeInvisible(codePoint)) {
cir.setReturnValue(this.viaFabricPlus$getBlankGlyphPair());
}
}
@Inject(method = "findGlyphRenderer", at = @At("RETURN"), cancellable = true)
private void filterGlyphRenderer(int codePoint, CallbackInfoReturnable<GlyphRenderer> cir) {
private void filterGlyphs2(int codePoint, CallbackInfoReturnable<GlyphRenderer> cir, @Local Font font) {
if (this.viaFabricPlus$shouldBeInvisible(codePoint)) {
cir.setReturnValue(this.viaFabricPlus$getBlankGlyphRenderer());
}
@ -87,11 +90,7 @@ public abstract class MixinFontStorage {
@Unique
private boolean viaFabricPlus$shouldBeInvisible(final int codePoint) {
if (VisualSettings.global().filterNonExistingGlyphs.getValue()) {
return (this.id.equals(MinecraftClient.DEFAULT_FONT_ID) || this.id.equals(MinecraftClient.UNICODE_FONT_ID)) && !RenderableGlyphDiff.isGlyphRenderable(codePoint);
} else {
return false;
}
return (this.id.equals(MinecraftClient.DEFAULT_FONT_ID) || this.id.equals(MinecraftClient.UNICODE_FONT_ID)) && !RenderableGlyphDiff.isGlyphRenderable(codePoint);
}
@Unique

View File

@ -20,15 +20,21 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.client.option.GameOptions;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
@Mixin(GameOptions.class)
public abstract class MixinGameOptions {
@Shadow
public boolean useNativeTransport;
@ModifyVariable(method = "setServerViewDistance", at = @At("HEAD"), ordinal = 0, argsOnly = true)
private int changeServerViewDistance(int viewDistance) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_17_1)) {
@ -38,4 +44,16 @@ public abstract class MixinGameOptions {
}
}
/**
* @author RK_01
* @reason Needed as an indicator if the client wants to ping a server or connect to a server
*/
@Overwrite
public boolean shouldUseNativeTransport() {
if (!this.useNativeTransport) {
ViaFabricPlus.global().getLogger().error("Native transport is disabled, but enabling it anyway since we use it as an indicator if the client wants to ping a server or connect to a server.");
}
return true;
}
}

View File

@ -42,7 +42,7 @@ public abstract class MixinGameRenderer {
@Final
MinecraftClient client;
@ModifyExpressionValue(method = "findCrosshairTarget", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;raycast(DFZ)Lnet/minecraft/util/hit/HitResult;"))
@ModifyExpressionValue(method = "updateTargetedEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;raycast(DFZ)Lnet/minecraft/util/hit/HitResult;"))
private HitResult bedrockReachAroundRaycast(HitResult hitResult) {
if (ProtocolTranslator.getTargetVersion().equals(BedrockProtocolVersion.bedrockLatest)) {
final Entity entity = this.client.getCameraEntity();

View File

@ -23,9 +23,9 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocols.v1_11_1to1_12.Protocol1_11_1To1_12;
import com.viaversion.viaversion.protocols.v1_9_1to1_9_3.packet.ServerboundPackets1_9_3;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_12to1_11_1.Protocol1_12To1_11_1;
import com.viaversion.viaversion.protocols.protocol1_9_3to1_9_1_2.ServerboundPackets1_9_3;
import de.florianmichael.viafabricplus.fixes.data.ItemRegistryDiff;
import de.florianmichael.viafabricplus.injection.access.IMouseKeyboard;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
@ -120,11 +120,11 @@ public abstract class MixinMinecraftClient {
}
@Inject(method = "handleInputEvents", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/tutorial/TutorialManager;onInventoryOpened()V", shift = At.Shift.AFTER))
private void sendOpenInventoryPacket(CallbackInfo ci) {
private void sendOpenInventoryPacket(CallbackInfo ci) throws Exception {
if (DebugSettings.global().sendOpenInventoryPacket.isEnabled()) {
final PacketWrapper clientCommand = PacketWrapper.create(ServerboundPackets1_9_3.CLIENT_COMMAND, ProtocolTranslator.getPlayNetworkUserConnection());
clientCommand.write(Types.VAR_INT, 2); // Open Inventory Achievement
clientCommand.scheduleSendToServer(Protocol1_11_1To1_12.class);
final PacketWrapper clientStatus = PacketWrapper.create(ServerboundPackets1_9_3.CLIENT_STATUS, ProtocolTranslator.getPlayNetworkUserConnection());
clientStatus.write(Type.VAR_INT, 2); // Open Inventory Achievement
clientStatus.scheduleSendToServer(Protocol1_12To1_11_1.class);
}
}
@ -163,9 +163,4 @@ public abstract class MixinMinecraftClient {
return ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_7_6) && original;
}
@ModifyExpressionValue(method = "doItemUse", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;isBreakingBlock()Z"))
private boolean allowItemUsageAndBlockBreakAtTheSameTime(boolean original) {
return ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_7_6) && original;
}
}

View File

@ -1,101 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.client.sound.StaticSound;
import net.raphimc.viaaprilfools.api.AprilFoolsProtocolVersion;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import javax.sound.sampled.AudioFormat;
import java.nio.ByteBuffer;
@Mixin(StaticSound.class)
public abstract class MixinStaticSound {
@Shadow
@Final
private AudioFormat format;
@Inject(method = "<init>", at = @At("RETURN"))
private void modifyBuffer(ByteBuffer sample, AudioFormat format, CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().equals(AprilFoolsProtocolVersion.s3d_shareware)) {
this.viaFabricPlus$apply8BitSound(sample);
}
}
@Unique
private void viaFabricPlus$apply8BitSound(final ByteBuffer byteBuffer) {
if (byteBuffer == null) {
return;
}
if (this.format.getChannels() == 1) {
this.viaFabricPlus$apply8BitMono(byteBuffer);
} else {
this.viaFabricPlus$apply8BitStereo(byteBuffer);
}
}
@Unique
private void viaFabricPlus$apply8BitMono(final ByteBuffer byteBuffer) {
short short2 = 0;
int integer3 = 0;
while (byteBuffer.hasRemaining()) {
if (integer3 == 0) {
byteBuffer.mark();
short2 = (short) (byteBuffer.getShort() & 0xFFFFFFFC);
byteBuffer.reset();
integer3 = 15;
} else {
--integer3;
}
byteBuffer.putShort(short2);
}
byteBuffer.flip();
}
@Unique
private void viaFabricPlus$apply8BitStereo(final ByteBuffer byteBuffer) {
short short2 = 0;
short short3 = 0;
int integer4 = 0;
while (byteBuffer.hasRemaining()) {
if (integer4 == 0) {
byteBuffer.mark();
short2 = (short) (byteBuffer.getShort() & 0xFFFFFFFC);
short3 = (short) (byteBuffer.getShort() & 0xFFFFFFFC);
byteBuffer.reset();
integer4 = 15;
} else {
--integer4;
}
byteBuffer.putShort(short2);
byteBuffer.putShort(short3);
}
byteBuffer.flip();
}
}

View File

@ -1,42 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.util.math.MathHelper;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(StatusEffectInstance.class)
public abstract class MixinStatusEffectInstance {
@Redirect(method = "<init>(Lnet/minecraft/registry/entry/RegistryEntry;IIZZZLnet/minecraft/entity/effect/StatusEffectInstance;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/MathHelper;clamp(III)I"))
private int dontClampValue(int value, int min, int max) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_3)) {
return value;
} else {
return MathHelper.clamp(value, min, max);
}
}
}

View File

@ -19,16 +19,16 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import net.minecraft.util.StringHelper;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
@Mixin(StringHelper.class)
public abstract class MixinStringHelper {
@ModifyExpressionValue(method = "truncateChat", at = @At(value = "CONSTANT", args = "intValue=256"))
@ModifyConstant(method = "truncateChat", constant = @Constant(intValue = 256))
private static int modifyMaxChatLength(int constant) {
return ClientsideFixes.getChatLength();
}

View File

@ -1,54 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.client.font.TextRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
@Mixin(TextRenderer.Drawer.class)
public abstract class MixinTextRenderer_Drawer {
@Unique
private static final float viaFabricPlus$offset = 0.5F; // Magical offset to revert the changes done in 1.13 pre6->1.13 pre7
@ModifyArg(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/GlyphRenderer$Rectangle;<init>(FFFFFFFFF)V", ordinal = 0), index = 1)
private float fixStrikethroughMinY(float value) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_12_2)) {
return value - viaFabricPlus$offset;
} else {
return value;
}
}
@ModifyArg(method = "accept", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/GlyphRenderer$Rectangle;<init>(FFFFFFFFF)V", ordinal = 0), index = 3)
private float fixStrikethroughMaxY(float value) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_12_2)) {
return value - viaFabricPlus$offset;
} else {
return value;
}
}
}

View File

@ -1,42 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import de.florianmichael.viafabricplus.fixes.versioned.classic.CPEAdditions;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.biome.Biome;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(WorldRenderer.class)
public abstract class MixinWorldRenderer {
@Redirect(method = "renderWeather", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/biome/Biome;getPrecipitation(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/world/biome/Biome$Precipitation;"), require = 0)
private Biome.Precipitation forceSnow(Biome instance, BlockPos pos) {
if (CPEAdditions.isSnowing()) {
return Biome.Precipitation.SNOW;
} else {
return instance.getPrecipitation(pos);
}
}
}

View File

@ -19,13 +19,12 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.block;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -36,7 +35,7 @@ public abstract class MixinAbstractBlock {
@Inject(method = "calcBlockBreakingDelta", at = @At("HEAD"), cancellable = true)
private void changeMiningSpeedCalculation(BlockState state, PlayerEntity player, BlockView world, BlockPos pos, CallbackInfoReturnable<Float> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_4_6tor1_4_7)) {
if (DebugSettings.global().legacyMiningSpeeds.isEnabled()) {
final float hardness = state.getHardness(world, pos);
if (hardness == -1.0F) {
cir.setReturnValue(0.0F);

View File

@ -1,67 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.block;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.block.*;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(AbstractRailBlock.class)
public abstract class MixinAbstractRailBlock extends Block {
@Shadow
@Final
protected static VoxelShape ASCENDING_SHAPE;
@Unique
private static final VoxelShape viaFabricPlus$ascending_shape_r1_10_x = VoxelShapes.fullCube();
@Unique
private static final VoxelShape viaFabricPlus$ascending_shape_r1_9_x = Block.createCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 2.5D, 16.0D);
@Unique
private static final VoxelShape viaFabricPlus$ascending_shape_r1_8_x = Block.createCuboidShape(0.0D, 0.0D, 0.0D, 16.0D, 10.0D, 16.0D);
public MixinAbstractRailBlock(Settings settings) {
super(settings);
}
@Redirect(method = "getOutlineShape", at = @At(value = "FIELD", target = "Lnet/minecraft/block/AbstractRailBlock;ASCENDING_SHAPE:Lnet/minecraft/util/shape/VoxelShape;"))
private VoxelShape changeOutlineShape() {
if (ProtocolTranslator.getTargetVersion().equalTo(ProtocolVersion.v1_10)) {
return viaFabricPlus$ascending_shape_r1_10_x;
} else if (ProtocolTranslator.getTargetVersion().betweenInclusive(ProtocolVersion.v1_9, ProtocolVersion.v1_9_3)) {
return viaFabricPlus$ascending_shape_r1_9_x;
} else if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
return viaFabricPlus$ascending_shape_r1_8_x;
} else {
return ASCENDING_SHAPE;
}
}
}

View File

@ -28,8 +28,8 @@ import net.minecraft.item.DyeItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.ItemActionResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@ -41,15 +41,15 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(AbstractSignBlock.class)
public abstract class MixinAbstractSignBlock {
@Inject(method = "onUseWithItem", at = @At("HEAD"), cancellable = true)
private void changeInteractionCalculation(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable<ItemActionResult> cir) {
@Inject(method = "onUse", at = @At("HEAD"), cancellable = true)
private void changeInteractionCalculation(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable<ActionResult> cir) {
if (!world.isClient) {
return;
}
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_14_4)) {
// <= 1.14.4 doesn't have any sign interactions.
cir.setReturnValue(ItemActionResult.SUCCESS);
cir.setReturnValue(ActionResult.SUCCESS);
} else if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_19_4)) {
// Removes the isWaxed() condition and reverts the interaction changes from 1.19.4 -> 1.20 when signs
// got a front and back side.
@ -57,7 +57,7 @@ public abstract class MixinAbstractSignBlock {
final Item item = itemStack.getItem();
final boolean isSuccess = (item instanceof DyeItem || itemStack.isOf(Items.GLOW_INK_SAC) || itemStack.isOf(Items.INK_SAC)) && player.canModifyBlocks();
cir.setReturnValue(isSuccess ? ItemActionResult.SUCCESS : ItemActionResult.CONSUME);
cir.setReturnValue(isSuccess ? ActionResult.SUCCESS : ActionResult.CONSUME);
}
}

View File

@ -17,25 +17,26 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.block;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.item.FireChargeItem;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.ActionResult;
import net.minecraft.block.BambooBlock;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(FireChargeItem.class)
public abstract class MixinFireChargeItem {
@Mixin(BambooBlock.class)
public abstract class MixinBambooBlock {
@Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true)
private void disableClientSideUsage(ItemUsageContext context, CallbackInfoReturnable<ActionResult> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_14_4) && context.getWorld().isClient) {
cir.setReturnValue(ActionResult.SUCCESS);
@Inject(method = "isShapeFullCube", at = @At("HEAD"), cancellable = true)
private void changeBlockBoundingBox(BlockState state, BlockView world, BlockPos pos, CallbackInfoReturnable<Boolean> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_17)) {
cir.setReturnValue(true);
}
}

View File

@ -24,9 +24,8 @@ import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.block.BlockState;
import net.minecraft.block.DecoratedPotBlock;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.ItemActionResult;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@ -38,10 +37,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(DecoratedPotBlock.class)
public abstract class MixinDecoratedPotBlock {
@Inject(method = "onUseWithItem", at = @At("HEAD"), cancellable = true)
private void alwaysPass(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable<ItemActionResult> cir) {
@Inject(method = "onUse", at = @At("HEAD"), cancellable = true)
private void alwaysPass(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable<ActionResult> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_2)) {
cir.setReturnValue(ItemActionResult.SKIP_DEFAULT_BLOCK_INTERACTION);
cir.setReturnValue(ActionResult.PASS);
}
}

View File

@ -56,7 +56,7 @@ public abstract class MixinFarmlandBlock extends Block {
@Override
public VoxelShape getCullingShape(BlockState state, BlockView view, BlockPos pos) {
if (ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_9_3)) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_9_3)) {
return SHAPE;
} else {
return super.getCullingShape(state, view, pos);

View File

@ -22,7 +22,7 @@ package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.block;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.block.*;
import net.minecraft.util.ItemActionResult;
import net.minecraft.util.ActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
@ -51,10 +51,10 @@ public abstract class MixinFenceBlock extends HorizontalConnectingBlock {
super(radius1, radius2, boundingHeight1, boundingHeight2, collisionHeight, settings);
}
@Inject(method = "onUseWithItem", at = @At("HEAD"), cancellable = true)
private void alwaysSuccess(CallbackInfoReturnable<ItemActionResult> cir) {
@Inject(method = "onUse", at = @At("HEAD"), cancellable = true)
private void alwaysSuccess(CallbackInfoReturnable<ActionResult> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_10)) {
cir.setReturnValue(ItemActionResult.SUCCESS);
cir.setReturnValue(ActionResult.SUCCESS);
}
}
@ -97,7 +97,7 @@ public abstract class MixinFenceBlock extends HorizontalConnectingBlock {
final VoxelShape southShape = Block.createCuboidShape(h, (float) 0.0, h, i, height, 16.0);
final VoxelShape westShape = Block.createCuboidShape(0.0, (float) 0.0, h, i, height, i);
final VoxelShape eastShape = Block.createCuboidShape(h, (float) 0.0, h, 16.0, height, i);
final VoxelShape[] voxelShapes = new VoxelShape[]{
final VoxelShape[] voxelShapes = new VoxelShape[] {
VoxelShapes.empty(),
Block.createCuboidShape(f, (float) 0.0, h, g, height, 16.0D),
Block.createCuboidShape(0.0D, (float) 0.0, f, i, height, g),

View File

@ -22,7 +22,7 @@ package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.block;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.block.NoteBlock;
import net.minecraft.util.ItemActionResult;
import net.minecraft.util.ActionResult;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -31,10 +31,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(NoteBlock.class)
public abstract class MixinNoteBlock {
@Inject(method = "onUseWithItem", at = @At("HEAD"), cancellable = true)
private void cancelMobHeadUsage(CallbackInfoReturnable<ItemActionResult> cir) {
@Inject(method = "onUse", at = @At("HEAD"), cancellable = true)
private void cancelMobHeadUsage(CallbackInfoReturnable<ActionResult> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_19_4)) {
cir.setReturnValue(ItemActionResult.SUCCESS);
cir.setReturnValue(ActionResult.SUCCESS);
}
}

View File

@ -31,7 +31,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
public abstract class MixinAnimalEntity {
@Redirect(method = "interactMob", at = @At(value = "FIELD", target = "Lnet/minecraft/world/World;isClient:Z"))
private boolean changeIsClientCondition(World instance) {
private boolean fixIsClientCheck(World instance) {
return instance.isClient && ProtocolTranslator.getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_15);
}

View File

@ -1,41 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.entity.passive.ArmadilloEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ArmadilloEntity.class)
public abstract class MixinArmadilloEntity {
@Redirect(method = "interactMob", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/passive/ArmadilloEntity;isNotIdle()Z"))
private boolean changeCondition(ArmadilloEntity instance) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_5)) {
return false;
} else {
return instance.isNotIdle();
}
}
}

View File

@ -1,44 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 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 <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.entity.passive.AxolotlEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsage;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(AxolotlEntity.class)
public abstract class MixinAxolotlEntity {
@Redirect(method = "eat", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemUsage;exchangeStack(Lnet/minecraft/item/ItemStack;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;)Lnet/minecraft/item/ItemStack;"))
private ItemStack dontExchangeStack(ItemStack inputStack, PlayerEntity player, ItemStack outputStack) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_5)) {
return outputStack;
} else {
return ItemUsage.exchangeStack(inputStack, player, outputStack);
}
}
}

Some files were not shown because too many files have changed in this diff Show More