Compare commits
No commits in common. "main" and "v3.0.5" have entirely different histories.
3
.github/FUNDING.yml
vendored
@ -1,3 +0,0 @@
|
||||
github: FlorianMichael
|
||||
custom: ["https://florianmichael.de/donate"]
|
||||
ko_fi: rk_01
|
6
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -13,11 +13,9 @@ body:
|
||||
attributes:
|
||||
label: General Information
|
||||
description: |
|
||||
Please provide a ViaVersion dump, if you experience a crash, also the crash report (latest.log file). You can get both by
|
||||
going to `ViaFabricPlus -> Report issues` and using the buttons there.
|
||||
Please provide a list of all installed mods
|
||||
placeholder: |
|
||||
ViaVersion dump url: **paste here**
|
||||
Crash report url: **upload to mclo.gs and paste here**
|
||||
Example: "ViaFabricPlus, Fabric-API, Quilted-Fabric-API, ModMenu"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
44
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@ -1,44 +0,0 @@
|
||||
name: Feature Request
|
||||
description: Suggest a feature to be added in ViaFabricPlus
|
||||
labels: [ enhancement ]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Before requesting a new feature, please see if using latest build from https://github.com/ViaVersion/ViaFabricPlus/actions already includes a solution.**
|
||||
Whenever you see fit, you can upload images or videos to any of the text fields.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Problem Description
|
||||
description: |
|
||||
Describe the issue you are facing or why you need the feature to be added.
|
||||
placeholder: |
|
||||
I am always frustrated with...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Solution Description
|
||||
description: |
|
||||
Describe the solution you would like to see.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Alternatives
|
||||
description: |
|
||||
Describe alternatives you have considered.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional Info
|
||||
description: |
|
||||
Does the feature apply to any specific version or environment?
|
||||
validations:
|
||||
required: false
|
10
.github/dependabot.yml
vendored
@ -1,10 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gradle"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
16
.github/workflows/build.yml
vendored
@ -1,24 +1,24 @@
|
||||
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: actions/setup-java@v4
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
java-version: 17
|
||||
check-latest: true
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
- name: Upload Artifacts to GitHub
|
||||
uses: actions/upload-artifact@v4
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Artifacts
|
||||
path: build/libs/
|
||||
|
20
.github/workflows/update-gradle-wrapper.yml
vendored
@ -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
|
@ -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.
|
138
README.md
@ -12,47 +12,125 @@
|
||||
</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)
|
||||
|
||||
## Supported Server versions
|
||||
- Release (1.0.0 - 1.21.3)
|
||||
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 - 23w51b)
|
||||
- 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.40 ([Some features are missing](https://github.com/RaphiMC/ViaBedrock#features))
|
||||
- Snapshots (3D Shareware, 20w14infinite, Combat Test 8C)
|
||||
- Bedrock (1.20.0)
|
||||
|
||||
## 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 users
|
||||
### Detailed instructions for use are available [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)
|
||||
## Known incompatibilities
|
||||
### Breaks
|
||||
- ***[ViaFabric (*)](https://github.com/ViaVersion/ViaFabric)***
|
||||
- ***[krypton (<= 0.2.2)](https://github.com/astei/krypton)***
|
||||
- ***[MemoryLeakFix (<= 1.1.0)](https://github.com/fxmorin/MemoryLeakFix)***
|
||||
|
||||
## ViaFabric
|
||||
[ViaFabric](https://github.com/ViaVersion/ViaFabric) can be used for server-side purposes or when using older versions of the game.
|
||||
### Conflicts
|
||||
- ***[DashLoader (*)](https://github.com/alphaqu/DashLoader/tree/fabric-1.20)*** - Font rendering related fixes aren't working
|
||||
- ***[Armor Skin (*)](https://github.com/IzzyDotExe/ArmorSkin)*** - Beta HUD changes aren't working
|
||||
|
||||
### Does it work with ViaFabricPlus:
|
||||
## Feature list
|
||||
<details>
|
||||
<summary>Click to open</summary>
|
||||
|
||||
- No, ViaFabricPlus cannot be used with ViaFabric.
|
||||
- [x] Bounding boxes for all versions
|
||||
- [x] Entity interaction and movement related packet fixes
|
||||
- [x] Sync and async mouse/keyboard handling in <= 1.12.2
|
||||
- [x] Mining speeds and item attributes
|
||||
- [x] Filter item creative tabs for only available items
|
||||
- [x] Combat system in <= 1.8
|
||||
- [x] Tons of modifications to ViaVersion, ViaAprilFools, ViaLegacy and ViaBedrock to make it more legit (Metadata fixes, broken packets, edge-cases)
|
||||
- [x] Visual and screen related changes (newer Command Block features, GameMode selection, ...)
|
||||
- [x] Chat signatures (secure login) for all versions (1.19.0, 1.19.1, 1.19.2)
|
||||
- [x] Address parsing for all Minecraft versions
|
||||
- [x] PackFormats and HTTP Header for all resource pack versions
|
||||
- [x] Raytrace related fixes in <= 1.8
|
||||
- [x] Implementing HUD changes for <= b1.7.3
|
||||
- [x] Chat lengths of all versions
|
||||
- [x] Implementing non-sequenced block placement in <= 1.18.2
|
||||
- [x] Animation related fixes (1.7 Sneaking, c0.30 walking animation, ...)
|
||||
- [x] Fixed clientside packet handling (1.16.5 transactions, 1.19.0 tablist, ...)
|
||||
</details>
|
||||
|
||||
### Differences with ViaFabric:
|
||||
https://github.com/ViaVersion/ViaFabric?tab=readme-ov-file#differences-with-viafabricplus
|
||||
# For developers and translators
|
||||
### Contributions in the form of pull requests are always welcome, [here](docs/UPDATE_INSTRUCTIONS.md) are some guidelines for contributing to the project.
|
||||
#### A detailed TODO list can be found at the class header of [this](https://github.com/ViaVersion/ViaFabricPlus/blob/main/src/main/java/de/florianmichael/viafabricplus/ViaFabricPlus.java) file.
|
||||
|
||||
## Credits
|
||||
Special thanks to all our [Contributors](https://github.com/ViaVersion/ViaFabricPllus/graphs/contributors).
|
||||
|
||||
### Dependencies
|
||||
For compiling only! **You do not need to install these!**
|
||||
<details>
|
||||
<summary>Click to get a list of all dependencies</summary>
|
||||
|
||||
| Dependency | Download |
|
||||
|------------------------|------------------------------------------------------|
|
||||
| Fabric API | https://github.com/FabricMC/fabric |
|
||||
| Fabric Loader | https://github.com/FabricMC/fabric-loader |
|
||||
| Classic4J | https://github.com/FlorianMichael/Classic4J |
|
||||
| ViaVersion | https://github.com/ViaVersion/ViaVersion |
|
||||
| ViaBackwards | https://github.com/ViaVersion/ViaBackwards |
|
||||
| ViaLoader | https://github.com/ViaVersion/ViaLoader |
|
||||
| ViaLegacy | https://github.com/ViaVersion/ViaLegacy |
|
||||
| ViaAprilFools | https://github.com/ViaVersion/ViaAprilFools |
|
||||
| ViaBedrock | https://github.com/RaphiMC/ViaBedrock |
|
||||
| MinecraftAuth | https://github.com/RaphiMC/MinecraftAuth |
|
||||
| Netty-transport-RakNet | https://github.com/CloudburstMC/Network/tree/develop |
|
||||
| Reflect | https://github.com/Lenni0451/Reflect |
|
||||
| MCPing | https://github.com/Lenni0451/MCPing |
|
||||
| MixinExtras | https://github.com/LlamaLad7/MixinExtras |
|
||||
</details>
|
||||
|
||||
### 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.
|
||||
|
||||
### Include via Gradle/Maven
|
||||
```groovy
|
||||
repositories {
|
||||
maven {
|
||||
name = "ViaVersion"
|
||||
url = "https://repo.viaversion.com"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
modImplementation("de.florianmichael:viafabricplus:3.0.2") // Get the latest version from releases
|
||||
}
|
||||
```
|
||||
|
||||
```xml
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>viaversion</id>
|
||||
<url>https://repo.viaversion.com</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>de.florianmichael</groupId>
|
||||
<artifactId>viafabricplus</artifactId>
|
||||
<version>3.0.2</version> <!-- Get the latest version from releases -->
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
### To learn more about the API and about addons, you can simply click [here](docs/DEVELOPER_API.md)
|
||||
|
||||
## Disclaimer
|
||||
|
||||
It cannot be guaranteed that this mod is allowed on specific servers as it can possibly cause problems with anti-cheat plugins.\
|
||||
***(USE ONLY WITH CAUTION!)***
|
||||
|
||||
### If you want to talk with me, feel free to join my [Discord](https://discord.gg/BwWhCHUKDf)
|
125
build.gradle
@ -1,14 +1,12 @@
|
||||
plugins {
|
||||
id "idea"
|
||||
id "fabric-loom" version "1.4-SNAPSHOT"
|
||||
id "maven-publish"
|
||||
id "fabric-loom" version "1.8-SNAPSHOT"
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -22,6 +20,10 @@ configurations {
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = "Jitpack"
|
||||
url = "https://jitpack.io"
|
||||
}
|
||||
maven {
|
||||
name = "ViaVersion"
|
||||
url = "https://repo.viaversion.com"
|
||||
@ -30,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/"
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,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))
|
||||
@ -65,75 +63,61 @@ 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.3"
|
||||
|
||||
jij "com.viaversion:viaversion-common:5.1.2-SNAPSHOT"
|
||||
jij "com.viaversion:viabackwards-common:5.1.2-SNAPSHOT"
|
||||
jij "net.raphimc:viaaprilfools-common:3.0.5-SNAPSHOT"
|
||||
jij "net.raphimc:ViaLegacy:3.0.6-SNAPSHOT"
|
||||
jij ("net.raphimc:ViaBedrock:0.0.13-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.5-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: "org.apache.httpcomponents", module: "httpclient"
|
||||
exclude group: "com.google.code.gson", module: "gson"
|
||||
exclude group: "org.slf4j", module: "slf4j-api"
|
||||
}
|
||||
jij "net.lenni0451:Reflect:1.4.0"
|
||||
jij("net.lenni0451:MCPing:1.4.2") {
|
||||
|
||||
// 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())))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
|
||||
filesMatching("fabric.mod.json") {
|
||||
expand(
|
||||
"version": project.version,
|
||||
"description": project.description,
|
||||
"implVersion": "git-${project.name}-${project.version}:${latestCommitHash().get()}",
|
||||
"mcVersion": mcVersion()
|
||||
)
|
||||
expand "version": project.version
|
||||
}
|
||||
}
|
||||
|
||||
String mcVersion() {
|
||||
if (project.supported_versions.isEmpty()) {
|
||||
return project.minecraft_version
|
||||
} else {
|
||||
return project.supported_versions
|
||||
}
|
||||
}
|
||||
|
||||
Provider<String> latestCommitHash() {
|
||||
return providers.exec {
|
||||
commandLine = ["git", "rev-parse", "--short", "HEAD"]
|
||||
}.standardOutput.getAsText().map(String::trim)
|
||||
}
|
||||
|
||||
java {
|
||||
withSourcesJar()
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
jar {
|
||||
@ -159,37 +143,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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,77 +1,14 @@
|
||||
# Developer API
|
||||
ViaFabricPlus provides events and various utility functions for other mods to interface with it. Note that including
|
||||
ViaFabricPlus in your project comes with some requirements:
|
||||
- The target version is Java 17
|
||||
- Fabric loom setup (As ViaFabricPlus is a Minecraft mod and has no API-only dependency like other projects)
|
||||
ViaFabricPlus provides various events and APIs for developers to use. This page explains how to use them.
|
||||
|
||||
Since the API is not exposed as standalone submodule (yet), functions that shouldn't be used are marked with
|
||||
`ApiStatus.Internal`. Further information about certain functions can be found in the Javadoc in the corresponding file.
|
||||
|
||||
## How to include the mod as dependency
|
||||
### Gradle
|
||||
```groovy
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = "ViaVersion"
|
||||
url = "https://repo.viaversion.com"
|
||||
}
|
||||
maven {
|
||||
name = "Lenni0451"
|
||||
url = "https://maven.lenni0451.net/everything"
|
||||
}
|
||||
maven {
|
||||
name = "Jitpack"
|
||||
url = "https://jitpack.io"
|
||||
|
||||
content {
|
||||
includeGroup "com.github.Oryxel"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
modImplementation("de.florianmichael:ViaFabricPlus:x.x.x") // Get the latest version from releases
|
||||
}
|
||||
```
|
||||
|
||||
### Maven
|
||||
```xml
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>viaversion</id>
|
||||
<url>https://repo.viaversion.com</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>lenni0451</id>
|
||||
<url>https://maven.lenni0451.net/everything</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jitpack</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>de.florianmichael</groupId>
|
||||
<artifactId>ViaFabricPlus</artifactId>
|
||||
<version>x.x.x</version> <!-- Get the latest version from releases -->
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
## Interacting with Events
|
||||
ViaFabricPlus events are the intended way of interacting with the mod.
|
||||
Events are fired in various situations and are using the [Fabric Event API](https://fabricmc.net/wiki/tutorial:events).
|
||||
|
||||
#### Example
|
||||
## Events
|
||||
ViaFabricPlus events are using the [Fabric Event API](https://fabricmc.net/wiki/tutorial:events). You can register to them like this:
|
||||
```java
|
||||
ChangeProtocolVersionCallback.EVENT.register((oldVersion, newVersion) -> {
|
||||
System.out.println("Version changed to " + newVersion.getName());
|
||||
});
|
||||
```
|
||||
### List of events/callbacks
|
||||
### ViaFabricPlus has 8 events at the moment
|
||||
| Callback class name | Description |
|
||||
|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| ChangeProtocolVersionCallback | Called when the user changes the target version in the screen, or if you connect to a server for which a specific version has been selected, you disconnect, the event for the actual version is also called. |
|
||||
@ -83,21 +20,71 @@ ChangeProtocolVersionCallback.EVENT.register((oldVersion, newVersion) -> {
|
||||
| RegisterSettingsCallback | Called after the default setting groups are loaded and before the setting config is loaded |
|
||||
| LoadSaveFilesCallback | Called before and after the save files are loaded |
|
||||
|
||||
### Other API calls
|
||||
|
||||
ViaFabricPlus uses [ViaVersion](https://github.com/ViaVersion/ViaVersion) for protocol translation, so the ViaVersion API can be used.
|
||||
|
||||
The general API endpoint for ViaFabricPlus specifics is `ProtocolTranslator`
|
||||
## Get and set the current protocol version
|
||||
```java
|
||||
// Get and change the current selected version
|
||||
final ProtocolVersion version = ProtocolTranslator.getTargetVersion();
|
||||
if (version == ProtocolVersion.v1_8) {
|
||||
ProtocolTranslator.setTargetVersion(ProtocolVersion.v1_9);
|
||||
final VersionEnum version = ProtocolHack.getTargetVersion();
|
||||
if (version == VersionEnum.r1_8) {
|
||||
ProtocolHack.setTargetVersion(VersionEnum.r1_9);
|
||||
}
|
||||
```
|
||||
|
||||
// Gets the ViaVersion user connection object for raw packet sending using ViaVersion API
|
||||
final UserConnection user = ProtocolTranslator.getPlayNetworkUserConnection();
|
||||
if (user == null) {
|
||||
// Mod not active
|
||||
## Get a Minecraft ClientConnection by channel
|
||||
```java
|
||||
final ClientConnection connection = channel.attr(ProtocolHack.CLIENT_CONNECTION_ATTRIBUTE_KEY).get();
|
||||
```
|
||||
|
||||
## Interact with UserConnection objects
|
||||
```java
|
||||
// If ViaVersion is translating, this field will return the user connection of the client
|
||||
final UserConnection userConnection = ProtocolHack.getPlayNetworkUserConnection();
|
||||
|
||||
// If you need a dummy user connection for testing, you can use this method
|
||||
final UserConnection cursedDummy = ProtocolHack.createDummyUserConnection(ProtocolHack.NATIVE_VERSION, VersionEnum.r1_18_2);
|
||||
// The cursedDummy field now contains all protocols from the native version to 1.18.2
|
||||
```
|
||||
|
||||
## ViaVersion internals
|
||||
### Add CustomPayload channels for versions below 1.13
|
||||
In order to receive custom payloads with custom channels in versions below 1.13, you need to register them, that's what you do:
|
||||
```java
|
||||
Protocol1_13To1_12_2.MAPPINGS.getChannelMappings().put("FML|HS", "fml:hs");
|
||||
```
|
||||
|
||||
### Check if an item exists in a specific version
|
||||
```java
|
||||
final VersionRange range = ItemRegistryDiff.ITEM_DIFF.get(Items.WRITABLE_BOOK); // If an item does not appear in the item map, it has always existed
|
||||
|
||||
// The Range class then contains all versions in which the item occurs.
|
||||
// https://github.com/ViaVersion/ViaLoader
|
||||
if (ItemRegistryDiff.contains(Items.STONE, VersionRange.andOlder(VersionEnum.r1_8))) {
|
||||
// Do something
|
||||
}
|
||||
```
|
||||
```
|
||||
|
||||
### Creating own settings for the settings screen
|
||||
```java
|
||||
public class ExampleSettingGroup extends SettingGroup {
|
||||
|
||||
private static final ExampleSettingGroup INSTANCE = new ExampleSettingGroup();
|
||||
|
||||
public final BooleanSetting test = new BooleanSetting(this, Text.of("Test"), false);
|
||||
|
||||
public ExampleSettingGroup() {
|
||||
super("Example");
|
||||
}
|
||||
|
||||
public static ExampleSettingGroup global() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
and then you register the setting group in your onLoad method
|
||||
```java
|
||||
RegisterSettingsCallback.EVENT.register(state -> {
|
||||
if (state == RegisterSettingsCallback.State.POST) {
|
||||
ViaFabricPlus.global().getSettingsManager().addGroup(ExampleSettingGroup.INSTANCE);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
@ -1,99 +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. Increment the version number in `gradle.properties` by at least a minor version (e.g. 1.0.0 -> 1.1.0)
|
||||
3. 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)
|
||||
- `EntityDimensionDiff` (add entity dimension changes)
|
||||
4. Update the `NATIVE_VERSION` field in the ProtocolTranslator class to the new version
|
||||
5. Update protocol constants in the `ViaFabricPlusProtocol` class
|
||||
-------------
|
||||
6. Check all mixins in the injection package if they still apply correctly, here is a list of some critical ones:
|
||||
- `MixinClientWorld#tickEntity` and `MixinClientWorld#tickPassenger`
|
||||
- `MixinPlayer#getBlockBreakingSpeed`
|
||||
7. mDecompile the game source code with the tool of your choice.
|
||||
8. Try to compile the mod and start porting the code until all existing fixes are working again.
|
||||
9. 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 (mojang mappings):
|
||||
- `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 (mojang mappings) 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`
|
||||
|
||||
10. 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.
|
||||
11. Run the game and check all GUIs and other visuals for issues.
|
||||
12. 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.
|
||||
-------------
|
||||
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.
|
65
docs/UPDATE_INSTRUCTIONS.md
Normal file
@ -0,0 +1,65 @@
|
||||
# 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!
|
||||
|
||||
## 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 ProtocolHack 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`, ...)
|
@ -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,21 +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.
|
||||
|
||||
#### Bedrock Realms
|
||||
If you have a Bedrock account set in the settings, you can view its Bedrock Realms in the "Server lists" screen (can be found at the left bottom of the main GUI).
|
||||
![](preview/bedrock_realms.png)
|
||||
|
||||
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 a "Server lists" button where you can go to ClassiCube and BetaCraft server lists.
|
||||
|
||||
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**.
|
||||
|
Before Width: | Height: | Size: 540 KiB |
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 155 KiB |
Before Width: | Height: | Size: 746 KiB After Width: | Height: | Size: 746 KiB |
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
@ -2,17 +2,33 @@
|
||||
org.gradle.jvmargs=-Xmx8G
|
||||
org.gradle.parallel=true
|
||||
|
||||
# Project Details
|
||||
maven_group=de.florianmichael
|
||||
maven_name=ViaFabricPlus
|
||||
maven_version=3.5.2-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.3
|
||||
yarn_version=1.21.3+build.2
|
||||
loader_version=0.16.9
|
||||
fabric_api_version=0.108.0+1.21.3
|
||||
minecraft_version=1.20.4
|
||||
yarn_mappings=1.20.4+build.3
|
||||
loader_version=0.15.3
|
||||
fabric_api_version=0.91.3+1.20.4
|
||||
|
||||
# Set to empty to use the Minecraft version above
|
||||
supported_versions=>=1.21.2 <=1.21.3
|
||||
# Project Details
|
||||
mod_version=3.0.5
|
||||
maven_group=de.florianmichael
|
||||
archives_base_name=viafabricplus
|
||||
|
||||
# ViaVersion Libraries
|
||||
viaversion_version=4.10.0-23w51b-SNAPSHOT
|
||||
viabackwards_version=4.10.0-23w51b-SNAPSHOT
|
||||
vialegacy_version=2.2.22-SNAPSHOT
|
||||
viaaprilfools_version=2.0.11-SNAPSHOT
|
||||
viabedrock_version=0.0.4-SNAPSHOT
|
||||
vialoader_version=2.2.13-SNAPSHOT
|
||||
|
||||
# RaphiMC Libraries
|
||||
minecraftauth_version=3.1.0-SNAPSHOT
|
||||
raknet_transport_version=1.0.0.CR1-SNAPSHOT
|
||||
|
||||
# Lenni0451 Libraries
|
||||
reflect_version=1.3.1
|
||||
mcping_version=1.4.0
|
||||
|
||||
# Misc Libraries
|
||||
mod_menu_version=9.0.0
|
||||
classic4j_version=2.0.1
|
||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,7 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=57dafb5c2622c6cc08b993c85b7c06956a2f53536432a30ead46166dbca0f1e9
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
21
gradlew
vendored
@ -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
|
||||
@ -148,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
# shellcheck disable=SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
@ -156,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
# shellcheck disable=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@ -205,11 +202,11 @@ fi
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
|
186
gradlew.bat
vendored
@ -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.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
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
|
||||
|
@ -1,7 +1,6 @@
|
||||
# Deploys the latest stable JDK 21 available and sets it to default without having to manually specify it here,
|
||||
# Deploys the latest stable JDK 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
|
||||
- curl -s "https://get.sdkman.io" | bash
|
||||
- source ~/.sdkman/bin/sdkman-init.sh
|
||||
- sdk install java
|
@ -21,7 +21,8 @@ package de.florianmichael.viafabricplus;
|
||||
|
||||
import de.florianmichael.viafabricplus.event.PostGameLoadCallback;
|
||||
import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import de.florianmichael.viafabricplus.protocolhack.util.VersionEnumExtension;
|
||||
import de.florianmichael.viafabricplus.save.SaveManager;
|
||||
import de.florianmichael.viafabricplus.settings.SettingsManager;
|
||||
import de.florianmichael.viafabricplus.util.ClassLoaderPriorityUtil;
|
||||
@ -33,36 +34,20 @@ import java.io.File;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/*
|
||||
* TODO | Port 1.21.3
|
||||
* - VehicleMovePacket handling now has distance check in ClientPlayNetworkHandler
|
||||
* - Illusioner/Sniffer don't override visibility bounding box anymore
|
||||
* - AbstractFireabll/EyeOfEnder#shouldRender new
|
||||
* - Entity#baseTick doesn't set prev rotation anymore at top
|
||||
* - LivingEntity movement code got refactored completely
|
||||
* - BundleItem#use, ConsumableComponent behaviour in use functions
|
||||
* - Check all screen handlers for changes
|
||||
*
|
||||
* 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
|
||||
* - 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
|
||||
* - X/Z Face based jump movement in <= 1.13.2 is broken (https://github.com/ViaVersion/ViaFabricPlus/issues/189)
|
||||
* - Collision hit boxes has been changed (https://github.com/ViaVersion/ViaFabricPlus/issues/195)
|
||||
* - Blip-jumping is not supported in <= 1.8.9 (https://github.com/ViaVersion/ViaFabricPlus/issues/225)
|
||||
* - Older versions don't clamp positions when teleporting (Is this important?)
|
||||
*/
|
||||
public class ViaFabricPlus {
|
||||
|
||||
@ -76,21 +61,19 @@ public class ViaFabricPlus {
|
||||
|
||||
private CompletableFuture<Void> loadingFuture;
|
||||
|
||||
public void init() {
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
public void bootstrap() {
|
||||
directory.mkdir();
|
||||
ClassLoaderPriorityUtil.loadOverridingJars(directory); // Load overriding jars first so other code can access the new classes
|
||||
VersionEnumExtension.init(); // Register extra VersionEnum values
|
||||
|
||||
settingsManager = new SettingsManager();
|
||||
saveManager = new SaveManager(settingsManager);
|
||||
|
||||
ClientsideFixes.init(); // Init clientside related fixes
|
||||
loadingFuture = ProtocolTranslator.init(directory); // Init ViaVersion protocol translator platform
|
||||
loadingFuture = ProtocolHack.init(directory); // Init ViaVersion protocol translator platform
|
||||
|
||||
// Block game loading until ViaVersion has loaded
|
||||
PostGameLoadCallback.EVENT.register(() -> {
|
||||
loadingFuture.join();
|
||||
saveManager.postInit();
|
||||
});
|
||||
PostGameLoadCallback.EVENT.register(() -> loadingFuture.join()); // Block game loading until ViaVersion has loaded
|
||||
}
|
||||
|
||||
public static ViaFabricPlus global() {
|
||||
|
@ -19,9 +19,9 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.event;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
|
||||
/**
|
||||
* This event is fired when the user changes the target version in the screen, or if the user joins a server with a different version.
|
||||
@ -35,6 +35,6 @@ public interface ChangeProtocolVersionCallback {
|
||||
}
|
||||
});
|
||||
|
||||
void onChangeProtocolVersion(final ProtocolVersion oldVersion, final ProtocolVersion newVersion);
|
||||
void onChangeProtocolVersion(final VersionEnum oldVersion, final VersionEnum newVersion);
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned;
|
||||
package de.florianmichael.viafabricplus.fixes;
|
||||
|
||||
import net.minecraft.util.ActionResult;
|
||||
|
@ -17,40 +17,38 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned.visual;
|
||||
package de.florianmichael.viafabricplus.fixes;
|
||||
|
||||
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.protocolhack.ProtocolHack;
|
||||
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.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;
|
||||
}
|
||||
|
||||
if (MinecraftClient.getInstance().player != null) {
|
||||
final UserConnection userConnection = ProtocolTranslator.getPlayNetworkUserConnection();
|
||||
final UserConnection userConnection = ProtocolHack.getPlayNetworkUserConnection();
|
||||
if (userConnection != null) {
|
||||
try {
|
||||
sendArmorUpdate(userConnection);
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -17,20 +17,19 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned;
|
||||
package de.florianmichael.viafabricplus.fixes;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import de.florianmichael.viafabricplus.ViaFabricPlus;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec2f;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
public class ClientPlayerInteractionManager1_18_2 {
|
||||
@ -38,10 +37,10 @@ public class ClientPlayerInteractionManager1_18_2 {
|
||||
private final Object2ObjectLinkedOpenHashMap<Pair<BlockPos, PlayerActionC2SPacket.Action>, Pair<Vec3d, Vec2f>> unAckedActions = new Object2ObjectLinkedOpenHashMap<>();
|
||||
|
||||
public void trackPlayerAction(final PlayerActionC2SPacket.Action action, final BlockPos blockPos) {
|
||||
final ClientPlayerEntity player = MinecraftClient.getInstance().player;
|
||||
final var player = MinecraftClient.getInstance().player;
|
||||
|
||||
final Vec2f rotation;
|
||||
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_16_1)) {
|
||||
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_1)) {
|
||||
rotation = null;
|
||||
} else {
|
||||
rotation = new Vec2f(player.getYaw(), player.getPitch());
|
||||
@ -52,15 +51,14 @@ public class ClientPlayerInteractionManager1_18_2 {
|
||||
public void handleBlockBreakAck(final BlockPos blockPos, final BlockState expectedState, final PlayerActionC2SPacket.Action action, final boolean allGood) {
|
||||
final var player = MinecraftClient.getInstance().player;
|
||||
if (player == null) return;
|
||||
|
||||
final var world = MinecraftClient.getInstance().getNetworkHandler().getWorld();
|
||||
|
||||
final var oldPlayerState = unAckedActions.remove(Pair.of(blockPos, action));
|
||||
final var actualState = world.getBlockState(blockPos);
|
||||
|
||||
if ((oldPlayerState == null || !allGood || action != PlayerActionC2SPacket.Action.START_DESTROY_BLOCK && actualState != expectedState) && (actualState != expectedState || ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_15_2))) {
|
||||
if ((oldPlayerState == null || !allGood || action != PlayerActionC2SPacket.Action.START_DESTROY_BLOCK && actualState != expectedState) && (actualState != expectedState || ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_15_2))) {
|
||||
world.setBlockState(blockPos, expectedState, Block.NOTIFY_ALL | Block.FORCE_STATE);
|
||||
if (oldPlayerState != null && (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_16_1) || (world == player.getWorld() && player.collidesWithStateAtPos(blockPos, expectedState)))) {
|
||||
if (oldPlayerState != null && (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_1) || (world == player.getWorld() && player.collidesWithStateAtPos(blockPos, expectedState)))) {
|
||||
final Vec3d oldPlayerPosition = oldPlayerState.getKey();
|
||||
if (oldPlayerState.getValue() != null) {
|
||||
player.updatePositionAndAngles(oldPlayerPosition.x, oldPlayerPosition.y, oldPlayerPosition.z, oldPlayerState.getValue().x, oldPlayerState.getValue().y);
|
@ -19,39 +19,24 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback;
|
||||
import de.florianmichael.viafabricplus.event.LoadClassicProtocolExtensionCallback;
|
||||
import de.florianmichael.viafabricplus.event.PostGameLoadCallback;
|
||||
import de.florianmichael.viafabricplus.fixes.data.EntityDimensionDiff;
|
||||
import de.florianmichael.viafabricplus.fixes.classic.CPEAdditions;
|
||||
import de.florianmichael.viafabricplus.fixes.classic.GridItemSelectionScreen;
|
||||
import de.florianmichael.viafabricplus.fixes.data.ResourcePackHeaderDiff;
|
||||
import de.florianmichael.viafabricplus.fixes.data.recipe.Recipes1_11_2;
|
||||
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 de.florianmichael.viafabricplus.fixes.entity.EntityDimensionReplacements;
|
||||
import de.florianmichael.viafabricplus.fixes.particle.FootStepParticle;
|
||||
import de.florianmichael.viafabricplus.injection.ViaFabricPlusMixinPlugin;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.font.FontStorage;
|
||||
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.vialoader.util.VersionEnum;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
@ -64,35 +49,33 @@ 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 {
|
||||
/**
|
||||
* The current chat limit
|
||||
*/
|
||||
private static int currentChatLength = 256;
|
||||
|
||||
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();
|
||||
EntityDimensionReplacements.init();
|
||||
|
||||
// Ticks the armor hud manually in <= 1.8.x
|
||||
ArmorHudEmulation1_8.init();
|
||||
@ -100,7 +83,24 @@ public class ClientsideFixes {
|
||||
|
||||
// Reloads some clientside stuff when the protocol version changes
|
||||
ChangeProtocolVersionCallback.EVENT.register((oldVersion, newVersion) -> MinecraftClient.getInstance().execute(() -> {
|
||||
VisualSettings.global().filterNonExistingGlyphs.onValueChanged();
|
||||
// Calculates the current chat length limit
|
||||
if (newVersion.isOlderThanOrEqualTo(VersionEnum.c0_28toc0_30)) {
|
||||
currentChatLength = 64 - (MinecraftClient.getInstance().getSession().getUsername().length() + 2);
|
||||
} else if (newVersion.equals(VersionEnum.bedrockLatest)) {
|
||||
currentChatLength = 512;
|
||||
} else if (newVersion.isOlderThanOrEqualTo(VersionEnum.r1_9_3tor1_9_4)) {
|
||||
currentChatLength = 100;
|
||||
} else {
|
||||
currentChatLength = 256;
|
||||
}
|
||||
|
||||
if (!ViaFabricPlusMixinPlugin.DASH_LOADER_PRESENT) {
|
||||
// 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) {
|
||||
@ -120,95 +120,47 @@ public class ClientsideFixes {
|
||||
}
|
||||
|
||||
// Rebuilds the item selection screen grid
|
||||
if (newVersion.olderThanOrEqualTo(LegacyProtocolVersion.c0_28toc0_30)) {
|
||||
if (newVersion.isOlderThanOrEqualTo(VersionEnum.c0_28toc0_30)) {
|
||||
GridItemSelectionScreen.INSTANCE.itemGrid = null;
|
||||
}
|
||||
|
||||
// Reloads the clientside recipes
|
||||
if (newVersion.olderThanOrEqualTo(ProtocolVersion.v1_11_1)) {
|
||||
Recipes1_11_2.reset();
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the maximum chat length for the selected protocol version in {@link ProtocolTranslator#getTargetVersion()}
|
||||
*
|
||||
* @return The maximum chat length
|
||||
*/
|
||||
public static int getChatLength() {
|
||||
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.c0_28toc0_30)) {
|
||||
final ClientPlayNetworkHandler handler = MinecraftClient.getInstance().getNetworkHandler();
|
||||
final ExtensionProtocolMetadataStorage extensionProtocol = ((IClientConnection) handler.getConnection()).viaFabricPlus$getUserConnection().get(ExtensionProtocolMetadataStorage.class);
|
||||
|
||||
if (extensionProtocol != null && extensionProtocol.hasServerExtension(ClassicProtocolExtension.LONGER_MESSAGES)) {
|
||||
return Short.MAX_VALUE * 2;
|
||||
} else {
|
||||
return 64 - (MinecraftClient.getInstance().getSession().getUsername().length() + 2);
|
||||
// Calculates the current chat limit, since it changes depending on the protocol version
|
||||
LoadClassicProtocolExtensionCallback.EVENT.register(classicProtocolExtension -> {
|
||||
if (classicProtocolExtension == ClassicProtocolExtension.LONGER_MESSAGES) {
|
||||
currentChatLength = Short.MAX_VALUE * 2;
|
||||
}
|
||||
} else if (ProtocolTranslator.getTargetVersion().equals(BedrockProtocolVersion.bedrockLatest)) {
|
||||
return 512;
|
||||
} else if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_9_3)) {
|
||||
return 100;
|
||||
} else {
|
||||
return 256;
|
||||
}
|
||||
});
|
||||
|
||||
// Register the footstep particle
|
||||
FootStepParticle.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the default port when parsing a server address if the default port should be replaced
|
||||
*
|
||||
* @param address The original address of the server
|
||||
* @param version The protocol version
|
||||
* @return The server address with the replaced default port
|
||||
*/
|
||||
public static String 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;
|
||||
} else {
|
||||
return 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) {
|
||||
final String uuid = UUID.randomUUID().toString();
|
||||
public static String executeSyncTask(final Consumer<PacketByteBuf> task) {
|
||||
final var 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();
|
||||
final var uuid = buf.readString();
|
||||
|
||||
if (PENDING_EXECUTION_TASKS.containsKey(uuid)) {
|
||||
MinecraftClient.getInstance().execute(() -> { // Execute the task on the main thread
|
||||
final var task = PENDING_EXECUTION_TASKS.remove(uuid);
|
||||
task.accept(new RegistryByteBuf(buf, MinecraftClient.getInstance().getNetworkHandler().getRegistryManager()));
|
||||
task.accept(buf);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static int getCurrentChatLength() {
|
||||
return currentChatLength;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -17,18 +17,15 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned.classic;
|
||||
package de.florianmichael.viafabricplus.fixes.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.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -36,29 +33,15 @@ 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);
|
||||
}
|
@ -17,16 +17,14 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned.classic;
|
||||
package de.florianmichael.viafabricplus.fixes.classic;
|
||||
|
||||
import de.florianmichael.viafabricplus.fixes.data.ItemRegistryDiff;
|
||||
import de.florianmichael.viafabricplus.screen.VFPScreen;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.resource.featuretoggle.FeatureFlags;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -57,7 +55,6 @@ public class GridItemSelectionScreen extends VFPScreen {
|
||||
final List<Item> allowedItems = new ArrayList<>();
|
||||
// Calculate all visible items
|
||||
for (Item item : Registries.ITEM) {
|
||||
if (item == Items.AIR || !item.getRequiredFeatures().contains(FeatureFlags.VANILLA)) continue;
|
||||
if (ItemRegistryDiff.keepItem(item)) {
|
||||
allowedItems.add(item);
|
||||
}
|
||||
@ -90,15 +87,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;
|
@ -17,28 +17,29 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned.classic;
|
||||
package de.florianmichael.viafabricplus.fixes.classic;
|
||||
|
||||
import com.viaversion.nbt.tag.CompoundTag;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
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 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 com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
|
||||
import com.viaversion.viaversion.libs.opennbt.tag.builtin.IntTag;
|
||||
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ListTag;
|
||||
import com.viaversion.viaversion.libs.opennbt.tag.builtin.Tag;
|
||||
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 net.raphimc.vialoader.util.VersionEnum;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public class WorldHeightSupport {
|
||||
|
||||
public static PacketHandler handleJoinGame(final PacketHandler parentHandler) {
|
||||
@ -46,11 +47,11 @@ public class WorldHeightSupport {
|
||||
parentHandler.handle(wrapper);
|
||||
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)) {
|
||||
changeDimensionTagHeight(wrapper.user(), dimension.getCompoundTag("element"));
|
||||
if (VersionEnum.fromUserConnection(wrapper.user()).isOlderThanOrEqualTo(VersionEnum.c0_28toc0_30)) {
|
||||
for (Tag dimension : wrapper.get(Type.NAMED_COMPOUND_TAG, 0).<CompoundTag>get("minecraft:dimension_type").<ListTag>get("value")) {
|
||||
changeDimensionTagHeight(wrapper.user(), ((CompoundTag) dimension).get("element"));
|
||||
}
|
||||
changeDimensionTagHeight(wrapper.user(), wrapper.get(Types.NAMED_COMPOUND_TAG, 1));
|
||||
changeDimensionTagHeight(wrapper.user(), wrapper.get(Type.NAMED_COMPOUND_TAG, 1));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -60,8 +61,8 @@ public class WorldHeightSupport {
|
||||
parentHandler.handle(wrapper);
|
||||
if (wrapper.isCancelled()) return;
|
||||
|
||||
if (wrapper.user().getProtocolInfo().serverProtocolVersion().olderThanOrEqualTo(LegacyProtocolVersion.c0_28toc0_30)) {
|
||||
changeDimensionTagHeight(wrapper.user(), wrapper.get(Types.NAMED_COMPOUND_TAG, 0));
|
||||
if (VersionEnum.fromUserConnection(wrapper.user()).isOlderThanOrEqualTo(VersionEnum.c0_28toc0_30)) {
|
||||
changeDimensionTagHeight(wrapper.user(), wrapper.get(Type.NAMED_COMPOUND_TAG, 0));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -71,7 +72,7 @@ public class WorldHeightSupport {
|
||||
parentHandler.handle(wrapper);
|
||||
if (wrapper.isCancelled()) return;
|
||||
|
||||
if (wrapper.user().getProtocolInfo().serverProtocolVersion().olderThanOrEqualTo(LegacyProtocolVersion.c0_28toc0_30)) {
|
||||
if (VersionEnum.fromUserConnection(wrapper.user()).isOlderThanOrEqualTo(VersionEnum.c0_28toc0_30)) {
|
||||
wrapper.resetReader();
|
||||
final Chunk chunk = wrapper.read(new ChunkType1_17(16));
|
||||
wrapper.write(new ChunkType1_17(chunk.getSections().length), chunk);
|
||||
@ -105,14 +106,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 +125,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,25 +144,25 @@ 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));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return wrapper -> {
|
||||
if (wrapper.user().getProtocolInfo().serverProtocolVersion().olderThanOrEqualTo(LegacyProtocolVersion.c0_28toc0_30)) {
|
||||
if (VersionEnum.fromUserConnection(wrapper.user()).isOlderThanOrEqualTo(VersionEnum.c0_28toc0_30)) {
|
||||
classicLightHandler.handle(wrapper);
|
||||
} else {
|
||||
parentHandler.handle(wrapper);
|
||||
@ -170,7 +171,7 @@ public class WorldHeightSupport {
|
||||
}
|
||||
|
||||
private static void changeDimensionTagHeight(final UserConnection user, final CompoundTag tag) {
|
||||
tag.putInt("height", Via.getManager().getProviders().get(ClassicWorldHeightProvider.class).getMaxChunkSectionCount(user) << 4);
|
||||
tag.put("height", new IntTag(Via.getManager().getProviders().get(ClassicWorldHeightProvider.class).getMaxChunkSectionCount(user) << 4));
|
||||
}
|
||||
|
||||
}
|
@ -17,16 +17,17 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned.classic.command;
|
||||
package de.florianmichael.viafabricplus.fixes.classic.command;
|
||||
|
||||
import com.viaversion.viaversion.api.command.ViaCommandSender;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import de.florianmichael.viafabricplus.injection.access.IExtensionProtocolMetadataStorage;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.impl.command.VFPViaSubCommand;
|
||||
import de.florianmichael.viafabricplus.protocolhack.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;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
|
||||
public class ListExtensionsCommand implements VFPViaSubCommand {
|
||||
public class ListExtensionsCommand extends VFPViaSubCommand {
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
@ -35,16 +36,17 @@ public class ListExtensionsCommand implements VFPViaSubCommand {
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Shows all classic extensions (only for " + LegacyProtocolVersion.c0_30cpe.getName() + ")";
|
||||
return "Shows all classic extensions (only for " + VersionEnum.c0_30cpe.getName() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(ViaCommandSender sender, String[] args) {
|
||||
if (getUser() == null || !getUser().has(ExtensionProtocolMetadataStorage.class)) {
|
||||
sendMessage(sender, Formatting.RED + "Only for " + LegacyProtocolVersion.c0_30cpe.getName());
|
||||
final UserConnection connection = getUser();
|
||||
if (!connection.has(ExtensionProtocolMetadataStorage.class)) {
|
||||
sendMessage(sender, Formatting.RED + "Only for " + VersionEnum.c0_30cpe.getName());
|
||||
return true;
|
||||
}
|
||||
((IExtensionProtocolMetadataStorage) getUser().get(ExtensionProtocolMetadataStorage.class)).viaFabricPlus$getServerExtensions().forEach((extension, version) -> {
|
||||
((IExtensionProtocolMetadataStorage) connection.get(ExtensionProtocolMetadataStorage.class)).viaFabricPlus$getServerExtensions().forEach((extension, version) -> {
|
||||
sendMessage(sender, Formatting.GREEN + extension.getName() + Formatting.GOLD + " v" + version);
|
||||
});
|
||||
return true;
|
@ -17,15 +17,16 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned.classic.command;
|
||||
package de.florianmichael.viafabricplus.fixes.classic.command;
|
||||
|
||||
import com.viaversion.viaversion.api.command.ViaCommandSender;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.impl.command.VFPViaSubCommand;
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import de.florianmichael.viafabricplus.protocolhack.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;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
|
||||
public class SetTimeCommand implements VFPViaSubCommand {
|
||||
public class SetTimeCommand extends VFPViaSubCommand {
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
@ -34,7 +35,7 @@ public class SetTimeCommand implements VFPViaSubCommand {
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "Changes the time (Only for <= " + LegacyProtocolVersion.a1_0_16toa1_0_16_2.getName() + ")";
|
||||
return "Changes the time (Only for <= " + VersionEnum.a1_0_16toa1_0_16_2.getName() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -44,14 +45,15 @@ public class SetTimeCommand implements VFPViaSubCommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(ViaCommandSender sender, String[] args) {
|
||||
if (getUser() == null || !getUser().has(TimeLockStorage.class)) {
|
||||
sendMessage(sender, Formatting.RED + "Only for <= " + LegacyProtocolVersion.a1_0_16toa1_0_16_2.getName());
|
||||
final UserConnection connection = getUser();
|
||||
if (!connection.has(TimeLockStorage.class)) {
|
||||
sendMessage(sender, Formatting.RED + "Only for <= " + VersionEnum.a1_0_16toa1_0_16_2.getName());
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
if (args.length == 1) {
|
||||
final long time = Long.parseLong(args[0]) % 24_000L;
|
||||
getUser().get(TimeLockStorage.class).setTime(time);
|
||||
connection.get(TimeLockStorage.class).setTime(time);
|
||||
sendMessage(sender, Formatting.GREEN + "Time has been set to " + Formatting.GOLD + time);
|
||||
} else {
|
||||
return false;
|
@ -1,215 +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.data;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback;
|
||||
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.Map;
|
||||
|
||||
import static de.florianmichael.viafabricplus.util.MapUtil.linkedHashMap;
|
||||
|
||||
/**
|
||||
* Data dump for entity dimension changes between versions.
|
||||
*/
|
||||
public class EntityDimensionDiff {
|
||||
|
||||
/**
|
||||
* A map of entity types to a map of versions to dimensions.
|
||||
*/
|
||||
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_8, EntityType.WITHER.getDimensions()
|
||||
),
|
||||
EntityType.SILVERFISH, linkedHashMap(
|
||||
ProtocolVersion.v1_7_6, EntityDimensionsBuilder.create(EntityType.SILVERFISH).withChangingDimensions(0.3F, 0.7F).build(),
|
||||
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_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_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(),
|
||||
ProtocolVersion.v1_8, EntityType.CHICKEN.getDimensions()
|
||||
),
|
||||
EntityType.SHEEP, linkedHashMap(
|
||||
LegacyProtocolVersion.c0_28toc0_30, EntityDimensionsBuilder.create(EntityType.SHEEP).withChangingDimensions(1.4F, 1.72F).build(),
|
||||
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_8, EntityType.OCELOT.getDimensions()
|
||||
),
|
||||
EntityType.OAK_BOAT, linkedHashMap(
|
||||
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.OAK_BOAT).withChangingDimensions(1.5F, 0.6F).build(),
|
||||
ProtocolVersion.v1_9, EntityType.OAK_BOAT.getDimensions()
|
||||
),
|
||||
EntityType.CREEPER, linkedHashMap(
|
||||
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.CREEPER).withChangingDimensions(0.6F, 1.8F).build(),
|
||||
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_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_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(),
|
||||
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_9, EntityType.COW.getDimensions()
|
||||
),
|
||||
EntityType.HORSE, linkedHashMap(
|
||||
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.HORSE).withChangingDimensions(1.4F, 1.6F).build(),
|
||||
ProtocolVersion.v1_9, EntityType.HORSE.getDimensions()
|
||||
),
|
||||
EntityType.MOOSHROOM, linkedHashMap(
|
||||
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.MOOSHROOM).withChangingDimensions(0.9F, 1.3F).build(),
|
||||
ProtocolVersion.v1_9, EntityType.MOOSHROOM.getDimensions()
|
||||
),
|
||||
EntityType.RABBIT, linkedHashMap(
|
||||
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.RABBIT).withChangingDimensions(0.6F, 0.7F).build(),
|
||||
ProtocolVersion.v1_9, EntityType.RABBIT.getDimensions()
|
||||
),
|
||||
EntityType.SQUID, linkedHashMap(
|
||||
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.SQUID).withChangingDimensions(0.95F, 0.95F).build(),
|
||||
ProtocolVersion.v1_9, EntityType.SQUID.getDimensions()
|
||||
),
|
||||
EntityType.VILLAGER, linkedHashMap(
|
||||
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.VILLAGER).withChangingDimensions(0.6F, 1.8F).build(),
|
||||
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(),
|
||||
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_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_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()
|
||||
),
|
||||
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()
|
||||
),
|
||||
EntityType.ARROW, linkedHashMap(
|
||||
LegacyProtocolVersion.c0_28toc0_30, EntityDimensionsBuilder.create(EntityType.ARROW).withChangingDimensions(0.3F, 0.5F).build(),
|
||||
LegacyProtocolVersion.a1_0_15, EntityType.ARROW.getDimensions()
|
||||
)
|
||||
);
|
||||
|
||||
static {
|
||||
ChangeProtocolVersionCallback.EVENT.register((oldVersion, newVersion) -> MinecraftClient.getInstance().execute(() -> ENTITY_DIMENSIONS.forEach((entityType, dimensionMap) -> {
|
||||
for (Map.Entry<ProtocolVersion, EntityDimensions> entry : dimensionMap.entrySet()) {
|
||||
final ProtocolVersion version = entry.getKey();
|
||||
final EntityDimensions dimensions = entry.getValue();
|
||||
if (oldVersion.newerThan(version) && newVersion.olderThanOrEqualTo(version)) {
|
||||
entityType.dimensions = dimensions;
|
||||
break;
|
||||
}
|
||||
if (newVersion.newerThanOrEqualTo(version) && oldVersion.olderThanOrEqualTo(version)) {
|
||||
entityType.dimensions = dimensions;
|
||||
}
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
// Calls the static block
|
||||
}
|
||||
|
||||
private static class EntityDimensionsBuilder {
|
||||
|
||||
private EntityDimensions entityDimensions;
|
||||
private EntityAttachments.Builder attachments = EntityAttachments.builder();
|
||||
|
||||
public static EntityDimensionsBuilder create() {
|
||||
return new EntityDimensionsBuilder();
|
||||
}
|
||||
|
||||
public static EntityDimensionsBuilder create(final EntityType<?> template) {
|
||||
final EntityDimensionsBuilder entityDimensionsBuilder = new EntityDimensionsBuilder();
|
||||
entityDimensionsBuilder.entityDimensions = template.getDimensions();
|
||||
return entityDimensionsBuilder;
|
||||
}
|
||||
|
||||
public EntityDimensionsBuilder withChangingDimensions(final float width, final float height) {
|
||||
this.entityDimensions = new EntityDimensions(width, height, this.entityDimensions.eyeHeight(), this.entityDimensions.attachments(), false);
|
||||
return this;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
this.entityDimensions = this.entityDimensions.withAttachments(this.attachments);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public EntityDimensions build() {
|
||||
return this.entityDimensions;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,11 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.data;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import net.minecraft.GameVersion;
|
||||
import net.minecraft.SaveVersion;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
@ -36,78 +34,79 @@ import java.util.Map;
|
||||
*/
|
||||
public class ResourcePackHeaderDiff {
|
||||
|
||||
private final static Map<ProtocolVersion, GameVersion> GAME_VERSION_DIFF = new HashMap<>();
|
||||
private final static Map<VersionEnum, GameVersion> GAME_VERSION_DIFF = new HashMap<>();
|
||||
|
||||
static {
|
||||
registerVersion(ProtocolVersion.v1_21_2, 42, "1.21.3");
|
||||
registerVersion(ProtocolVersion.v1_21, 34, "1.21.1");
|
||||
registerVersion(ProtocolVersion.v1_20_5, 32, "1.20.6");
|
||||
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");
|
||||
registerVersion(ProtocolVersion.v1_19_4, 13, "1.19.4");
|
||||
registerVersion(ProtocolVersion.v1_19_3, 12, "1.19.3");
|
||||
registerVersion(ProtocolVersion.v1_19_1, 9, "1.19.2");
|
||||
registerVersion(ProtocolVersion.v1_19, 9, "1.19");
|
||||
registerVersion(ProtocolVersion.v1_18_2, 8, "1.18.2");
|
||||
registerVersion(ProtocolVersion.v1_18, 8, "1.18.1");
|
||||
registerVersion(ProtocolVersion.v1_17_1, 7, "1.17.1");
|
||||
registerVersion(ProtocolVersion.v1_17, 7, "1.17");
|
||||
registerVersion(ProtocolVersion.v1_16_4, 6, "1.16.5");
|
||||
registerVersion(ProtocolVersion.v1_16_3, 6, "1.16.3");
|
||||
registerVersion(ProtocolVersion.v1_16_2, 6, "1.16.2");
|
||||
registerVersion(ProtocolVersion.v1_16_1, 5, "1.16.1");
|
||||
registerVersion(ProtocolVersion.v1_16, 5, "1.16");
|
||||
registerVersion(ProtocolVersion.v1_15_2, 5, "1.15.2");
|
||||
registerVersion(ProtocolVersion.v1_15_1, 5, "1.15.1");
|
||||
registerVersion(ProtocolVersion.v1_15, 5, "1.15");
|
||||
registerVersion(ProtocolVersion.v1_14_4, 4, "1.14.4");
|
||||
registerVersion(ProtocolVersion.v1_14_3, 4, "1.14.3");
|
||||
registerVersion(ProtocolVersion.v1_14_2, 4, "1.14.2");
|
||||
registerVersion(ProtocolVersion.v1_14_1, 4, "1.14.1");
|
||||
registerVersion(ProtocolVersion.v1_14, 4, "1.14");
|
||||
registerVersion(ProtocolVersion.v1_13_2, 4, "1.13.2");
|
||||
registerVersion(ProtocolVersion.v1_13_1, 4, "1.13.1");
|
||||
registerVersion(ProtocolVersion.v1_13, 4, "1.13");
|
||||
registerVersion(ProtocolVersion.v1_12_2, 3, "1.12.2");
|
||||
registerVersion(ProtocolVersion.v1_12_1, 3, "1.12.1");
|
||||
registerVersion(ProtocolVersion.v1_12, 3, "1.12");
|
||||
registerVersion(ProtocolVersion.v1_11_1, 3, "1.11.2");
|
||||
registerVersion(ProtocolVersion.v1_11, 3, "1.11");
|
||||
registerVersion(ProtocolVersion.v1_10, 2, "1.10.2");
|
||||
registerVersion(ProtocolVersion.v1_9_3, 2, "1.9.4");
|
||||
registerVersion(ProtocolVersion.v1_9_2, 2, "1.9.2");
|
||||
registerVersion(ProtocolVersion.v1_9_1, 2, "1.9.1");
|
||||
registerVersion(ProtocolVersion.v1_9, 2, "1.9");
|
||||
registerVersion(ProtocolVersion.v1_8, 1, "1.8.9");
|
||||
registerVersion(ProtocolVersion.v1_7_6, 1, "1.7.10");
|
||||
registerVersion(ProtocolVersion.v1_7_2, 1, "1.7.5");
|
||||
registerVersion(VersionEnum.r1_20_3tor1_20_4, 22, "1.20.4");
|
||||
registerVersion(VersionEnum.r1_20_2, 18, "1.20.2");
|
||||
registerVersion(VersionEnum.r1_20tor1_20_1, 15, "1.20.1");
|
||||
registerVersion(VersionEnum.r1_19_4, 13, "1.19.4");
|
||||
registerVersion(VersionEnum.r1_19_3, 12, "1.19.3");
|
||||
registerVersion(VersionEnum.r1_19_1tor1_19_2, 9, "1.19.2");
|
||||
registerVersion(VersionEnum.r1_19, 9, "1.19");
|
||||
registerVersion(VersionEnum.r1_18_2, 8, "1.18.2");
|
||||
registerVersion(VersionEnum.r1_18tor1_18_1, 8, "1.18.1");
|
||||
registerVersion(VersionEnum.r1_17_1, 7, "1.17.1");
|
||||
registerVersion(VersionEnum.r1_17, 7, "1.17");
|
||||
registerVersion(VersionEnum.r1_16_4tor1_16_5, 6, "1.16.5");
|
||||
registerVersion(VersionEnum.r1_16_3, 6, "1.16.3");
|
||||
registerVersion(VersionEnum.r1_16_2, 6, "1.16.2");
|
||||
registerVersion(VersionEnum.r1_16_1, 5, "1.16.1");
|
||||
registerVersion(VersionEnum.r1_16, 5, "1.16");
|
||||
registerVersion(VersionEnum.r1_15_2, 5, "1.15.2");
|
||||
registerVersion(VersionEnum.r1_15_1, 5, "1.15.1");
|
||||
registerVersion(VersionEnum.r1_15, 5, "1.15");
|
||||
registerVersion(VersionEnum.r1_14_4, 4, "1.14.4");
|
||||
registerVersion(VersionEnum.r1_14_3, 4, "1.14.3");
|
||||
registerVersion(VersionEnum.r1_14_2, 4, "1.14.2");
|
||||
registerVersion(VersionEnum.r1_14_1, 4, "1.14.1");
|
||||
registerVersion(VersionEnum.r1_14, 4, "1.14");
|
||||
registerVersion(VersionEnum.r1_13_2, 4, "1.13.2");
|
||||
registerVersion(VersionEnum.r1_13_1, 4, "1.13.1");
|
||||
registerVersion(VersionEnum.r1_13, 4, "1.13");
|
||||
registerVersion(VersionEnum.r1_12_2, 3, "1.12.2");
|
||||
registerVersion(VersionEnum.r1_12_1, 3, "1.12.1");
|
||||
registerVersion(VersionEnum.r1_12, 3, "1.12");
|
||||
registerVersion(VersionEnum.r1_11_1to1_11_2, 3, "1.11.2");
|
||||
registerVersion(VersionEnum.r1_11, 3, "1.11");
|
||||
registerVersion(VersionEnum.r1_10, 2, "1.10.2");
|
||||
registerVersion(VersionEnum.r1_9_3tor1_9_4, 2, "1.9.4");
|
||||
registerVersion(VersionEnum.r1_9_2, 2, "1.9.2");
|
||||
registerVersion(VersionEnum.r1_9_1, 2, "1.9.1");
|
||||
registerVersion(VersionEnum.r1_9, 2, "1.9");
|
||||
registerVersion(VersionEnum.r1_8, 1, "1.8.9");
|
||||
registerVersion(VersionEnum.r1_7_6tor1_7_10, 1, "1.7.10");
|
||||
registerVersion(VersionEnum.r1_7_2tor1_7_5, 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 (VersionEnum version : VersionEnum.OFFICIAL_SUPPORTED_PROTOCOLS) {
|
||||
if (version.getProtocol().isSnapshot()) continue;
|
||||
if (!GAME_VERSION_DIFF.containsKey(version)) {
|
||||
throw new RuntimeException("The version " + version + " has no pack format registered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param version The {@link ProtocolVersion} to get the {@link GameVersion} for.
|
||||
* @return The {@link GameVersion} for the given {@link ProtocolVersion}.
|
||||
* @param version The {@link VersionEnum} to get the {@link GameVersion} for.
|
||||
* @return The {@link GameVersion} for the given {@link VersionEnum}.
|
||||
*/
|
||||
public static GameVersion get(final ProtocolVersion version) {
|
||||
public static GameVersion get(final VersionEnum version) {
|
||||
if (!GAME_VERSION_DIFF.containsKey(version)) {
|
||||
return SharedConstants.getGameVersion();
|
||||
} else {
|
||||
return GAME_VERSION_DIFF.get(version);
|
||||
}
|
||||
return GAME_VERSION_DIFF.get(version);
|
||||
}
|
||||
|
||||
private static void registerVersion(final ProtocolVersion version, final int packFormat, final String name) {
|
||||
private static void registerVersion(final VersionEnum version, final int packFormat, final String name) {
|
||||
registerVersion(version, packFormat, name, name);
|
||||
}
|
||||
|
||||
private static void registerVersion(final ProtocolVersion version, final int packFormat, final String name, final String id) {
|
||||
private static void registerVersion(final VersionEnum version, final int packFormat, final String name, final String id) {
|
||||
GAME_VERSION_DIFF.put(version, new GameVersion() {
|
||||
|
||||
@Override
|
||||
@ -127,7 +126,7 @@ public class ResourcePackHeaderDiff {
|
||||
|
||||
@Override
|
||||
public int getProtocolVersion() {
|
||||
return version.getOriginalVersion();
|
||||
return version.getProtocol().getOriginalVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -19,22 +19,23 @@
|
||||
|
||||
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 de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import net.minecraft.block.entity.BannerBlockEntity;
|
||||
import net.minecraft.inventory.RecipeInputInventory;
|
||||
import net.minecraft.item.BannerItem;
|
||||
import net.minecraft.item.DyeItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtList;
|
||||
import net.minecraft.recipe.RecipeSerializer;
|
||||
import net.minecraft.recipe.SpecialCraftingRecipe;
|
||||
import net.minecraft.recipe.SpecialRecipeSerializer;
|
||||
import net.minecraft.recipe.book.CraftingRecipeCategory;
|
||||
import net.minecraft.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;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
|
||||
public class AddBannerPatternRecipe extends SpecialCraftingRecipe {
|
||||
|
||||
@ -45,27 +46,27 @@ public class AddBannerPatternRecipe extends SpecialCraftingRecipe {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(CraftingRecipeInput input, World world) {
|
||||
public boolean matches(RecipeInputInventory inv, World world) {
|
||||
boolean foundBanner = false;
|
||||
for (int i = 0; i < input.size(); i++) {
|
||||
ItemStack stack = input.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;
|
||||
}
|
||||
}
|
||||
return foundBanner && getBannerPattern(input) != null;
|
||||
return foundBanner && getBannerPattern(inv) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack craft(CraftingRecipeInput input, RegistryWrapper.WrapperLookup lookup) {
|
||||
public ItemStack craft(RecipeInputInventory inv, DynamicRegistryManager registryManager) {
|
||||
ItemStack result = ItemStack.EMPTY;
|
||||
|
||||
for (int i = 0; i < input.size(); i++) {
|
||||
ItemStack stack = input.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);
|
||||
@ -73,34 +74,44 @@ public class AddBannerPatternRecipe extends SpecialCraftingRecipe {
|
||||
}
|
||||
}
|
||||
|
||||
final BannerPattern_1_13_2 pattern = getBannerPattern(input);
|
||||
BannerPattern_1_13_2 pattern = getBannerPattern(inv);
|
||||
if (pattern != null) {
|
||||
final var patternKey = lookup.getOrThrow(RegistryKeys.BANNER_PATTERN).getOrThrow(pattern.getKey());
|
||||
DyeColor color = ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_12_2) ? DyeColor.BLACK : DyeColor.WHITE;
|
||||
for (int i = 0; i < input.size(); i++) {
|
||||
Item item = input.getStackInSlot(i).getItem();
|
||||
DyeColor color = ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_12_2) ? DyeColor.BLACK : DyeColor.WHITE;
|
||||
for (int i = 0; i < inv.size(); i++) {
|
||||
Item item = inv.getStack(i).getItem();
|
||||
if (item instanceof DyeItem dyeItem) {
|
||||
color = dyeItem.getColor();
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fits(int width, int height) {
|
||||
return width >= 3 && height >= 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeSerializer<AddBannerPatternRecipe> getSerializer() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
private static BannerPattern_1_13_2 getBannerPattern(CraftingRecipeInput input) {
|
||||
private static BannerPattern_1_13_2 getBannerPattern(RecipeInputInventory inv) {
|
||||
for (BannerPattern_1_13_2 pattern : BannerPattern_1_13_2.values()) {
|
||||
if (!pattern.isCraftable())
|
||||
continue;
|
||||
@ -109,8 +120,8 @@ public class AddBannerPatternRecipe extends SpecialCraftingRecipe {
|
||||
if (pattern.hasBaseStack()) {
|
||||
boolean foundBaseItem = false;
|
||||
boolean foundDye = false;
|
||||
for (int i = 0; i < input.size(); i++) {
|
||||
ItemStack stack = input.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) {
|
||||
@ -127,13 +138,13 @@ public class AddBannerPatternRecipe extends SpecialCraftingRecipe {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!foundBaseItem || (!foundDye && ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_10))) matches = false;
|
||||
} else if (input.size() == pattern.getRecipePattern().length * pattern.getRecipePattern()[0].length()) {
|
||||
if (!foundBaseItem || (!foundDye && ProtocolHack.getTargetVersion().isNewerThan(VersionEnum.r1_10))) matches = false;
|
||||
} else if (inv.size() == pattern.getRecipePattern().length * pattern.getRecipePattern()[0].length()) {
|
||||
DyeColor patternColor = null;
|
||||
for (int i = 0; i < input.size(); i++) {
|
||||
for (int i = 0; i < inv.size(); i++) {
|
||||
int row = i / 3;
|
||||
int col = i % 3;
|
||||
ItemStack stack = input.getStackInSlot(i);
|
||||
ItemStack stack = inv.getStack(i);
|
||||
Item item = stack.getItem();
|
||||
if (!stack.isEmpty() && !(item instanceof BannerItem)) {
|
||||
if (!(item instanceof DyeItem)) {
|
||||
|
@ -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() {
|
||||
|
@ -24,7 +24,7 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.recipe.*;
|
||||
import net.minecraft.recipe.book.CookingRecipeCategory;
|
||||
import net.minecraft.recipe.book.CraftingRecipeCategory;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.collection.DefaultedList;
|
||||
|
||||
import java.util.*;
|
||||
@ -109,20 +109,19 @@ public final class RecipeInfo {
|
||||
}
|
||||
|
||||
final int height = shape.size();
|
||||
final DefaultedList<Optional<Ingredient>> ingredients = DefaultedList.of();
|
||||
final DefaultedList<Ingredient> ingredients = DefaultedList.of();
|
||||
for (String row : shape) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
final char key = row.charAt(x);
|
||||
Ingredient ingredient = legend.get(key);
|
||||
if (ingredient == null) {
|
||||
if (key == ' ') {
|
||||
ingredients.add(Optional.empty());
|
||||
ingredient = Ingredient.EMPTY;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown character in shape: " + key);
|
||||
}
|
||||
} else {
|
||||
ingredients.add(Optional.of(ingredient));
|
||||
}
|
||||
ingredients.add(ingredient);
|
||||
}
|
||||
}
|
||||
|
||||
@ -316,8 +315,8 @@ public final class RecipeInfo {
|
||||
* @param id The id
|
||||
* @return The recipe info
|
||||
*/
|
||||
public RecipeEntry<?> create(RegistryKey<Recipe<?>> id) {
|
||||
return new RecipeEntry<>(id, this.creator.get());
|
||||
public RecipeEntry<?> create(Identifier id) {
|
||||
return new RecipeEntry<Recipe<?>>(id, this.creator.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,76 +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.data.recipe;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import net.minecraft.recipe.Recipe;
|
||||
import net.minecraft.recipe.RecipeEntry;
|
||||
import net.minecraft.recipe.RecipeType;
|
||||
import net.minecraft.recipe.input.RecipeInput;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class RecipeManager1_11_2 {
|
||||
|
||||
private final Multimap<RecipeType<?>, RecipeEntry<?>> recipesByType;
|
||||
private final Map<RegistryKey<Recipe<?>>, RecipeEntry<?>> recipesById;
|
||||
|
||||
public RecipeManager1_11_2(final Iterable<RecipeEntry<?>> recipes) {
|
||||
final ImmutableMultimap.Builder<RecipeType<?>, RecipeEntry<?>> recipesByTypeBuilder = ImmutableMultimap.builder();
|
||||
final ImmutableMap.Builder<RegistryKey<Recipe<?>>, RecipeEntry<?>> recipesByIdBuilder = ImmutableMap.builder();
|
||||
|
||||
for (RecipeEntry<?> recipeEntry : recipes) {
|
||||
final RecipeType<?> recipeType = recipeEntry.value().getType();
|
||||
recipesByTypeBuilder.put(recipeType, recipeEntry);
|
||||
recipesByIdBuilder.put(recipeEntry.id(), recipeEntry);
|
||||
}
|
||||
|
||||
this.recipesByType = recipesByTypeBuilder.build();
|
||||
this.recipesById = recipesByIdBuilder.build();
|
||||
}
|
||||
|
||||
public <I extends RecipeInput, T extends Recipe<I>> Optional<RecipeEntry<T>> getFirstMatch(final RecipeType<T> type, final I input, final World world) {
|
||||
if (input.isEmpty()) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return this.recipesByType.get(type).stream().map(e -> (RecipeEntry<T>) e).filter(recipe -> recipe.value().matches(input, world)).findFirst();
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<RecipeEntry<?>> get(final RegistryKey<Recipe<?>> id) {
|
||||
return Optional.ofNullable(this.recipesById.get(id));
|
||||
}
|
||||
|
||||
public Collection<RecipeEntry<?>> values() {
|
||||
return this.recipesById.values();
|
||||
}
|
||||
|
||||
public Stream<RegistryKey<Recipe<?>>> keys() {
|
||||
return this.recipesById.keySet().stream();
|
||||
}
|
||||
|
||||
}
|
@ -19,8 +19,6 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.data.recipe;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.inventory.RecipeInputInventory;
|
||||
@ -30,12 +28,9 @@ import net.minecraft.item.Items;
|
||||
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
|
||||
import net.minecraft.recipe.*;
|
||||
import net.minecraft.recipe.book.CraftingRecipeCategory;
|
||||
import net.minecraft.registry.RegistryKey;
|
||||
import net.minecraft.registry.RegistryKeys;
|
||||
import net.minecraft.registry.tag.ItemTags;
|
||||
import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -45,53 +40,33 @@ import java.util.List;
|
||||
*/
|
||||
public class Recipes1_11_2 {
|
||||
|
||||
private static RecipeManager1_11_2 RECIPE_MANAGER;
|
||||
|
||||
public static RecipeManager1_11_2 getRecipeManager() {
|
||||
if (RECIPE_MANAGER == null) {
|
||||
final List<RecipeInfo> recipeInfos = Recipes1_11_2.getRecipes(ProtocolTranslator.getTargetVersion());
|
||||
final List<RecipeEntry<?>> recipes = new ArrayList<>(recipeInfos.size());
|
||||
for (int i = 0; i < recipeInfos.size(); i++) {
|
||||
final RegistryKey<Recipe<?>> key = RegistryKey.of(RegistryKeys.RECIPE, Identifier.of("viafabricplus", "recipe/" + i));
|
||||
recipes.add(recipeInfos.get(i).create(key));
|
||||
}
|
||||
RECIPE_MANAGER = new RecipeManager1_11_2(recipes);
|
||||
}
|
||||
|
||||
return RECIPE_MANAGER;
|
||||
}
|
||||
|
||||
public static void reset() {
|
||||
RECIPE_MANAGER = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A list of all recipes for the given version.
|
||||
*/
|
||||
public static List<RecipeInfo> getRecipes(final ProtocolVersion targetVersion) {
|
||||
public static List<RecipeInfo> getRecipes(final VersionEnum targetVersion) {
|
||||
final List<RecipeInfo> recipes = new ArrayList<>();
|
||||
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_4_2)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_4_2)) {
|
||||
recipes.add(RecipeInfo.of(() -> new ArmorDyeRecipe(CraftingRecipeCategory.MISC)));
|
||||
recipes.add(RecipeInfo.of(() -> new MapCloningRecipe(CraftingRecipeCategory.MISC)));
|
||||
recipes.add(RecipeInfo.of(() -> new MapExtendingRecipe(CraftingRecipeCategory.MISC)));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_4_6tor1_4_7)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_4_6tor1_4_7)) {
|
||||
recipes.add(RecipeInfo.of(() -> new FireworkRocketRecipe(CraftingRecipeCategory.MISC)));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_11)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_11)) {
|
||||
recipes.add(RecipeInfo.of(() -> new ShulkerBoxColoringRecipe(CraftingRecipeCategory.MISC)));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_9)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_9)) {
|
||||
recipes.add(RecipeInfo.of(() -> new TippedArrowRecipe(CraftingRecipeCategory.MISC)));
|
||||
recipes.add(RecipeInfo.of(() -> new ShieldDecorationRecipe(CraftingRecipeCategory.MISC)));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_8)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_8)) {
|
||||
recipes.add(RecipeInfo.of(() -> new RepairItemRecipe(CraftingRecipeCategory.MISC)));
|
||||
recipes.add(RecipeInfo.of(() -> new BannerDuplicateRecipe(CraftingRecipeCategory.MISC)));
|
||||
recipes.add(RecipeInfo.of(() -> new AddBannerPatternRecipe(CraftingRecipeCategory.MISC)));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_7_2)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_7_2tor1_7_5)) {
|
||||
recipes.add(RecipeInfo.of(() -> new BookCloningRecipe(CraftingRecipeCategory.MISC)));
|
||||
}
|
||||
|
||||
@ -169,7 +144,7 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.BOOKSHELF, "###", "XXX", "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'X', Items.BOOK));
|
||||
recipes.add(RecipeInfo.shaped(4, Items.ARROW, "X", "#", "Y", '#', Items.STICK, 'X', Items.FLINT, 'Y', Items.FEATHER));
|
||||
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_12)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_12)) {
|
||||
recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.YELLOW_CONCRETE_POWDER, Items.YELLOW_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
|
||||
recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.WHITE_CONCRETE_POWDER, Items.BONE_MEAL, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
|
||||
recipes.add(RecipeInfo.shapeless("concrete_powder", 8, Blocks.RED_CONCRETE_POWDER, Items.RED_DYE, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.SAND, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL, Blocks.GRAVEL));
|
||||
@ -219,26 +194,26 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.shaped("bed", Blocks.BLACK_BED, "###", "XXX", '#', Blocks.BLACK_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
|
||||
} else {
|
||||
recipes.add(RecipeInfo.shapeless(Blocks.WHITE_WOOL, Blocks.WHITE_WOOL, Items.BONE_MEAL));
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_3tob1_3_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_3tob1_3_1)) {
|
||||
recipes.add(RecipeInfo.shaped("bed", Blocks.RED_BED, "###", "XXX", '#', Blocks.YELLOW_WOOL, Blocks.BLACK_WOOL, Blocks.BLUE_WOOL, Blocks.BROWN_WOOL, Blocks.CYAN_WOOL, Blocks.GRAY_WOOL, Blocks.GREEN_WOOL, Blocks.LIGHT_BLUE_WOOL, Blocks.LIGHT_GRAY_WOOL, Blocks.WHITE_WOOL, Blocks.RED_WOOL, Blocks.PURPLE_WOOL, Blocks.PINK_WOOL, Blocks.ORANGE_WOOL, Blocks.LIME_WOOL, Blocks.MAGENTA_WOOL, 'X', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
|
||||
}
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_11_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_11_1to1_11_2)) {
|
||||
recipes.add(RecipeInfo.shaped(9, Items.IRON_NUGGET, "#", '#', Items.IRON_INGOT));
|
||||
recipes.add(RecipeInfo.shaped("iron_ingot", Items.IRON_INGOT, "###", "###", "###", '#', Items.IRON_NUGGET));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_11)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_11)) {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.OBSERVER, "###", "RRQ", "###", 'Q', Items.QUARTZ, 'R', Blocks.REDSTONE_WIRE, '#', Blocks.COBBLESTONE));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.PURPLE_SHULKER_BOX, "-", "#", "-", '#', Blocks.CHEST, '-', Items.SHULKER_SHELL));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_10)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_10)) {
|
||||
recipes.add(RecipeInfo.shapeless("bonemeal", 9, Items.BONE_MEAL, Blocks.BONE_BLOCK));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.BONE_BLOCK, "XXX", "XXX", "XXX", 'X', Items.BONE_MEAL));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.MAGMA_BLOCK, "##", "##", '#', Items.MAGMA_CREAM));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.NETHER_WART_BLOCK, "###", "###", "###", '#', Blocks.NETHER_WART));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.RED_NETHER_BRICKS, "NW", "WN", 'W', Blocks.NETHER_WART, 'N', Items.NETHER_BRICK));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_9)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_9)) {
|
||||
recipes.add(RecipeInfo.shapeless(Blocks.TRAPPED_CHEST, Blocks.CHEST, Blocks.TRIPWIRE_HOOK));
|
||||
recipes.add(RecipeInfo.shaped(Items.SHIELD, "WoW", "WWW", " W ", 'W', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'o', Items.IRON_INGOT));
|
||||
recipes.add(RecipeInfo.shaped(4, Blocks.PURPUR_BLOCK, "FF", "FF", 'F', Items.POPPED_CHORUS_FRUIT));
|
||||
@ -258,15 +233,15 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.shapeless("red_dye", Items.RED_DYE, Items.BEETROOT));
|
||||
recipes.add(RecipeInfo.shaped(Items.BEETROOT_SOUP, "OOO", "OOO", " B ", 'B', Items.BOWL, 'O', Items.BEETROOT));
|
||||
} else {
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_5tor1_5_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_5tor1_5_1)) {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.TRAPPED_CHEST, "#-", '#', Blocks.CHEST, '-', Blocks.TRIPWIRE_HOOK));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_3_1tor1_3_2)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_3_1tor1_3_2)) {
|
||||
recipes.add(RecipeInfo.shaped(Items.ENCHANTED_GOLDEN_APPLE, "###", "#X#", "###", '#', Items.GOLD_BLOCK, 'X', Items.APPLE));
|
||||
}
|
||||
recipes.add(RecipeInfo.shaped("boat", Items.OAK_BOAT, "# #", "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.DARK_OAK_PLANKS, Blocks.BIRCH_PLANKS, Blocks.ACACIA_PLANKS));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_8)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_8)) {
|
||||
recipes.add(RecipeInfo.shapeless(Blocks.MOSSY_COBBLESTONE, Blocks.COBBLESTONE, Blocks.VINE));
|
||||
recipes.add(RecipeInfo.shapeless(Blocks.MOSSY_STONE_BRICKS, Blocks.STONE_BRICKS, Blocks.VINE));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.CHISELED_STONE_BRICKS, "#", "#", '#', Blocks.STONE_BRICK_SLAB));
|
||||
@ -330,13 +305,13 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.shaped(4, Blocks.POLISHED_ANDESITE, "SS", "SS", 'S', Blocks.ANDESITE));
|
||||
} else {
|
||||
recipes.add(RecipeInfo.shaped("wooden_fence", 2, Blocks.OAK_FENCE, "###", "###", '#', Items.STICK));
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_8tob1_8_1)) {
|
||||
recipes.add(RecipeInfo.shaped("wooden_fence_gate", Blocks.OAK_FENCE_GATE, "#W#", "#W#", '#', Items.STICK, 'W', Blocks.OAK_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.DARK_OAK_PLANKS, Blocks.BIRCH_PLANKS, Blocks.ACACIA_PLANKS));
|
||||
}
|
||||
recipes.add(RecipeInfo.shaped(Blocks.IRON_DOOR, "##", "##", "##", '#', Items.IRON_INGOT));
|
||||
recipes.add(RecipeInfo.shaped("wooden_door", Blocks.OAK_DOOR, "##", "##", "##", '#', Blocks.OAK_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.DARK_OAK_PLANKS, Blocks.BIRCH_PLANKS, Blocks.ACACIA_PLANKS));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_7_2)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_7_2tor1_7_5)) {
|
||||
recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.YELLOW_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.YELLOW_DYE));
|
||||
recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.WHITE_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.BONE_MEAL));
|
||||
recipes.add(RecipeInfo.shaped("stained_glass", 8, Blocks.RED_STAINED_GLASS, "###", "#X#", "###", '#', Blocks.GLASS, 'X', Items.RED_DYE));
|
||||
@ -393,7 +368,7 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.shaped(Items.FLINT_AND_STEEL, "A ", " B", 'A', Items.IRON_INGOT, 'B', Items.FLINT));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.TNT, "X#X", "#X#", "X#X", '#', Blocks.SAND, 'X', Items.GUNPOWDER));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_6_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_6_1)) {
|
||||
recipes.add(RecipeInfo.shaped(Items.GOLDEN_APPLE, "###", "#X#", "###", '#', Items.GOLD_INGOT, 'X', Items.APPLE));
|
||||
recipes.add(RecipeInfo.shaped(Items.GLISTERING_MELON_SLICE, "###", "#X#", "###", '#', Items.GOLD_NUGGET, 'X', Items.MELON_SLICE));
|
||||
recipes.add(RecipeInfo.shaped("carpet", 3, Blocks.YELLOW_CARPET, "##", '#', Blocks.YELLOW_WOOL));
|
||||
@ -435,11 +410,11 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.shaped(9, Items.COAL, "#", '#', Blocks.COAL_BLOCK));
|
||||
} else {
|
||||
recipes.add(RecipeInfo.shaped(Items.GOLDEN_APPLE, "###", "#X#", "###", '#', Items.GOLD_NUGGET, 'X', Items.APPLE));
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_0_0tor1_0_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_0_0tor1_0_1)) {
|
||||
recipes.add(RecipeInfo.shapeless(Items.GLISTERING_MELON_SLICE, Items.GOLD_NUGGET, Items.MELON_SLICE));
|
||||
}
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_5tor1_5_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_5tor1_5_1)) {
|
||||
recipes.add(RecipeInfo.shaped(6, Blocks.SNOW, "###", '#', Blocks.SNOW_BLOCK));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.QUARTZ_BLOCK, "##", "##", '#', Items.QUARTZ));
|
||||
recipes.add(RecipeInfo.shaped(2, Blocks.QUARTZ_PILLAR, "#", "#", '#', Blocks.QUARTZ_BLOCK));
|
||||
@ -459,10 +434,10 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.REDSTONE_BLOCK, "###", "###", "###", '#', Blocks.REDSTONE_WIRE));
|
||||
recipes.add(RecipeInfo.shaped(9, Blocks.REDSTONE_WIRE, "#", '#', Blocks.REDSTONE_BLOCK));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_4_6tor1_4_7)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_4_6tor1_4_7)) {
|
||||
recipes.add(RecipeInfo.shaped(6, Blocks.NETHER_BRICK_SLAB, "###", '#', Blocks.NETHER_BRICKS));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_4_2)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_4_2)) {
|
||||
recipes.add(RecipeInfo.shaped(6, Blocks.COBBLESTONE_WALL, "###", "###", '#', Blocks.COBBLESTONE));
|
||||
recipes.add(RecipeInfo.shaped(6, Blocks.MOSSY_COBBLESTONE_WALL, "###", "###", '#', Blocks.MOSSY_COBBLESTONE));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.FLOWER_POT, "# #", " # ", '#', Items.BRICK));
|
||||
@ -474,7 +449,7 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.BEACON, "GGG", "GSG", "OOO", 'S', Items.NETHER_STAR, 'G', Blocks.GLASS, 'O', Blocks.OBSIDIAN));
|
||||
recipes.add(RecipeInfo.shapeless(Items.PUMPKIN_PIE, Blocks.CARVED_PUMPKIN, Items.SUGAR, Items.EGG));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_3_1tor1_3_2)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_3_1tor1_3_2)) {
|
||||
recipes.add(RecipeInfo.shapeless(Items.WRITABLE_BOOK, Items.BOOK, Items.INK_SAC, Items.FEATHER));
|
||||
recipes.add(RecipeInfo.shapeless(Items.BOOK, Items.PAPER, Items.PAPER, Items.PAPER, Items.LEATHER));
|
||||
recipes.add(RecipeInfo.shaped(3, Blocks.OAK_SIGN, "###", "###", " X ", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'X', Items.STICK));
|
||||
@ -491,17 +466,17 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.EMERALD_BLOCK, "###", "###", "###", '#', Items.EMERALD));
|
||||
recipes.add(RecipeInfo.shaped(9, Items.EMERALD, "#", '#', Blocks.EMERALD_BLOCK));
|
||||
} else {
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_2_1tor1_2_3)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_2_1tor1_2_3)) {
|
||||
recipes.add(RecipeInfo.shaped("wooden_slab", 6, Blocks.OAK_SLAB, "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
|
||||
} else {
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_3tob1_3_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_3tob1_3_1)) {
|
||||
recipes.add(RecipeInfo.shaped("wooden_slab", 3, Blocks.OAK_SLAB, "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
|
||||
}
|
||||
}
|
||||
recipes.add(RecipeInfo.shaped(Items.BOOK, "#", "#", "#", '#', Items.PAPER));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.OAK_SIGN, "###", "###", " X ", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'X', Items.STICK));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_2_4tor1_2_5)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_2_4tor1_2_5)) {
|
||||
recipes.add(RecipeInfo.shaped("planks", 4, Blocks.BIRCH_PLANKS, "#", '#', Blocks.BIRCH_LOG));
|
||||
recipes.add(RecipeInfo.shaped("planks", 4, Blocks.SPRUCE_PLANKS, "#", '#', Blocks.SPRUCE_LOG));
|
||||
recipes.add(RecipeInfo.shaped("planks", 4, Blocks.JUNGLE_PLANKS, "#", '#', Blocks.JUNGLE_LOG));
|
||||
@ -510,7 +485,7 @@ public class Recipes1_11_2 {
|
||||
} else {
|
||||
recipes.add(RecipeInfo.shaped("planks", 4, Blocks.OAK_PLANKS, "#", '#', Blocks.BIRCH_LOG, Blocks.SPRUCE_LOG, Blocks.JUNGLE_LOG));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_2_1tor1_2_3)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_2_1tor1_2_3)) {
|
||||
recipes.add(RecipeInfo.shaped(3, Blocks.LADDER, "# #", "###", "# #", '#', Items.STICK));
|
||||
recipes.add(RecipeInfo.shaped(6, Blocks.SMOOTH_STONE_SLAB, "###", '#', Blocks.STONE));
|
||||
recipes.add(RecipeInfo.shaped(6, Blocks.SANDSTONE_SLAB, "###", '#', Blocks.SANDSTONE, Blocks.CHISELED_SANDSTONE, Blocks.CUT_SANDSTONE));
|
||||
@ -520,22 +495,22 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.REDSTONE_LAMP, " R ", "RGR", " R ", 'R', Blocks.REDSTONE_WIRE, 'G', Blocks.GLOWSTONE));
|
||||
recipes.add(RecipeInfo.shapeless(3, Items.FIRE_CHARGE, new ItemConvertible[]{Items.GUNPOWDER}, new ItemConvertible[]{Items.BLAZE_POWDER}, new ItemConvertible[]{Items.COAL, Items.CHARCOAL}));
|
||||
} else {
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_5tob1_5_2)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_5tob1_5_2)) {
|
||||
recipes.add(RecipeInfo.shaped(2, Blocks.LADDER, "# #", "###", "# #", '#', Items.STICK));
|
||||
} else {
|
||||
recipes.add(RecipeInfo.shaped(1, Blocks.LADDER, "# #", "###", "# #", '#', Items.STICK));
|
||||
}
|
||||
recipes.add(RecipeInfo.shaped(3, Blocks.SMOOTH_STONE_SLAB, "###", '#', Blocks.STONE));
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_3tob1_3_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_3tob1_3_1)) {
|
||||
recipes.add(RecipeInfo.shaped(3, Blocks.SANDSTONE_SLAB, "###", '#', Blocks.SANDSTONE, Blocks.CHISELED_SANDSTONE, Blocks.CUT_SANDSTONE));
|
||||
recipes.add(RecipeInfo.shaped(3, Blocks.COBBLESTONE_SLAB, "###", '#', Blocks.COBBLESTONE));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_8tob1_8_1)) {
|
||||
recipes.add(RecipeInfo.shaped(3, Blocks.BRICK_SLAB, "###", '#', Blocks.BRICKS));
|
||||
recipes.add(RecipeInfo.shaped(3, Blocks.STONE_BRICK_SLAB, "###", '#', Blocks.STONE_BRICKS, Blocks.MOSSY_STONE_BRICKS, Blocks.CRACKED_STONE_BRICKS, Blocks.CHISELED_STONE_BRICKS));
|
||||
}
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_0_0tor1_0_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_0_0tor1_0_1)) {
|
||||
recipes.add(RecipeInfo.shapeless(Items.MUSHROOM_STEW, Blocks.BROWN_MUSHROOM, Blocks.RED_MUSHROOM, Items.BOWL));
|
||||
recipes.add(RecipeInfo.shaped(4, Blocks.NETHER_BRICK_STAIRS, "# ", "## ", "###", '#', Blocks.NETHER_BRICKS));
|
||||
recipes.add(RecipeInfo.shaped(6, Blocks.NETHER_BRICK_FENCE, "###", "###", '#', Blocks.NETHER_BRICKS));
|
||||
@ -554,7 +529,7 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.shaped(Items.MUSHROOM_STEW, "Y", "X", "#", 'X', Blocks.BROWN_MUSHROOM, 'Y', Blocks.RED_MUSHROOM, '#', Items.BOWL));
|
||||
recipes.add(RecipeInfo.shaped(Items.MUSHROOM_STEW, "Y", "X", "#", 'X', Blocks.RED_MUSHROOM, 'Y', Blocks.BROWN_MUSHROOM, '#', Items.BOWL));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_8tob1_8_1)) {
|
||||
recipes.add(RecipeInfo.shaped(4, Blocks.BRICK_STAIRS, "# ", "## ", "###", '#', Blocks.BRICKS));
|
||||
recipes.add(RecipeInfo.shaped(4, Blocks.STONE_BRICK_STAIRS, "# ", "## ", "###", '#', Blocks.STONE_BRICKS, Blocks.MOSSY_STONE_BRICKS, Blocks.CRACKED_STONE_BRICKS, Blocks.CHISELED_STONE_BRICKS));
|
||||
recipes.add(RecipeInfo.shaped(4, Blocks.STONE_BRICKS, "##", "##", '#', Blocks.STONE));
|
||||
@ -563,30 +538,30 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.MELON, "MMM", "MMM", "MMM", 'M', Items.MELON_SLICE));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.MELON_STEM, "M", 'M', Items.MELON_SLICE));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_7tob1_7_3)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_7tob1_7_3)) {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.STICKY_PISTON, "S", "P", 'P', Blocks.PISTON, 'S', Items.SLIME_BALL));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.PISTON, "TTT", "#X#", "#R#", 'R', Blocks.REDSTONE_WIRE, '#', Blocks.COBBLESTONE, 'T', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'X', Items.IRON_INGOT));
|
||||
recipes.add(RecipeInfo.shaped(Items.SHEARS, " #", "# ", '#', Items.IRON_INGOT));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_6tob1_6_6)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_6tob1_6_6)) {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.GLOWSTONE, "##", "##", '#', Items.GLOWSTONE_DUST));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.WHITE_WOOL, "##", "##", '#', Blocks.TRIPWIRE));
|
||||
recipes.add(RecipeInfo.shaped(2, Blocks.OAK_TRAPDOOR, "###", "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
|
||||
recipes.add(RecipeInfo.shaped(Items.MAP, "###", "#X#", "###", '#', Items.PAPER, 'X', Items.COMPASS));
|
||||
} else {
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.a1_2_0toa1_2_1_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.a1_2_0toa1_2_1_1)) {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.GLOWSTONE, "###", "###", "###", '#', Items.GLOWSTONE_DUST));
|
||||
}
|
||||
recipes.add(RecipeInfo.shaped(Blocks.WHITE_WOOL, "###", "###", "###", '#', Blocks.TRIPWIRE));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_5tob1_5_2)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_5tob1_5_2)) {
|
||||
recipes.add(RecipeInfo.shaped(6, Blocks.DETECTOR_RAIL, "X X", "X#X", "XRX", 'R', Blocks.REDSTONE_WIRE, '#', Blocks.STONE_PRESSURE_PLATE, 'X', Items.IRON_INGOT));
|
||||
recipes.add(RecipeInfo.shaped(6, Blocks.POWERED_RAIL, "X X", "X#X", "XRX", 'R', Blocks.REDSTONE_WIRE, '#', Items.STICK, 'X', Items.GOLD_INGOT));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_4tob1_4_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_4tob1_4_1)) {
|
||||
recipes.add(RecipeInfo.shaped(8, Items.COOKIE, "#X#", '#', Items.WHEAT, 'X', Blocks.COCOA));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_3tob1_3_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_3tob1_3_1)) {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.REPEATER, "#X#", "III", '#', Blocks.REDSTONE_TORCH, 'X', Blocks.REDSTONE_WIRE, 'I', Blocks.STONE));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.OAK_PRESSURE_PLATE, "##", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.STONE_PRESSURE_PLATE, "##", '#', Blocks.STONE));
|
||||
@ -594,7 +569,7 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.OAK_PRESSURE_PLATE, "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.STONE_PRESSURE_PLATE, "###", '#', Blocks.STONE));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_2_0tob1_2_2)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_2_0tob1_2_2)) {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.NOTE_BLOCK, "###", "#X#", "###", '#', Blocks.OAK_PLANKS, Blocks.SPRUCE_PLANKS, Blocks.BIRCH_PLANKS, Blocks.JUNGLE_PLANKS, Blocks.ACACIA_PLANKS, Blocks.DARK_OAK_PLANKS, 'X', Blocks.REDSTONE_WIRE));
|
||||
recipes.add(RecipeInfo.shaped(Blocks.CAKE, "AAA", "BEB", "CCC", 'A', Items.MILK_BUCKET, 'B', Items.SUGAR, 'C', Items.WHEAT, 'E', Items.EGG));
|
||||
recipes.add(RecipeInfo.shaped(Items.SUGAR, "#", '#', Blocks.SUGAR_CANE));
|
||||
@ -636,11 +611,11 @@ public class Recipes1_11_2 {
|
||||
} else {
|
||||
recipes.add(RecipeInfo.shaped(4, Blocks.TORCH, "X", "#", '#', Items.STICK, 'X', Items.COAL));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.a1_2_0toa1_2_1_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.a1_2_0toa1_2_1_1)) {
|
||||
recipes.add(RecipeInfo.shaped(Blocks.JACK_O_LANTERN, "A", "B", 'A', Blocks.CARVED_PUMPKIN, 'B', Blocks.TORCH));
|
||||
recipes.add(RecipeInfo.shaped(Items.CLOCK, " # ", "#X#", " # ", '#', Items.GOLD_INGOT, 'X', Blocks.REDSTONE_WIRE));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.a1_1_0toa1_1_2_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.a1_1_0toa1_1_2_1)) {
|
||||
recipes.add(RecipeInfo.shaped(Items.FISHING_ROD, " #", " #X", "# X", '#', Items.STICK, 'X', Blocks.TRIPWIRE));
|
||||
recipes.add(RecipeInfo.shaped(Items.COMPASS, " # ", "#X#", " # ", '#', Items.IRON_INGOT, 'X', Blocks.REDSTONE_WIRE));
|
||||
}
|
||||
@ -648,12 +623,12 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.smelting(Items.IRON_INGOT, Items.IRON_ORE, 0.7F));
|
||||
recipes.add(RecipeInfo.smelting(Items.GOLD_INGOT, Items.GOLD_ORE, 1.0F));
|
||||
recipes.add(RecipeInfo.smelting(Items.DIAMOND, Items.DIAMOND_ORE, 1.0F));
|
||||
recipes.add(RecipeInfo.smelting(Items.GLASS, Ingredient.ofItems(Items.SAND, Items.RED_SAND), 0.1F));
|
||||
recipes.add(RecipeInfo.smelting(Items.GLASS, Ingredient.fromTag(ItemTags.SAND), 0.1F));
|
||||
recipes.add(RecipeInfo.smelting(Items.COOKED_PORKCHOP, Items.PORKCHOP, 0.35F));
|
||||
recipes.add(RecipeInfo.smelting(Items.STONE, Items.COBBLESTONE, 0.1F));
|
||||
recipes.add(RecipeInfo.smelting(Items.BRICK, Items.CLAY_BALL, 0.3F));
|
||||
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_12)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_12)) {
|
||||
recipes.add(RecipeInfo.smelting(Items.WHITE_GLAZED_TERRACOTTA, Items.WHITE_TERRACOTTA, 0.1F));
|
||||
recipes.add(RecipeInfo.smelting(Items.ORANGE_GLAZED_TERRACOTTA, Items.ORANGE_TERRACOTTA, 0.1F));
|
||||
recipes.add(RecipeInfo.smelting(Items.MAGENTA_GLAZED_TERRACOTTA, Items.MAGENTA_TERRACOTTA, 0.1F));
|
||||
@ -671,47 +646,47 @@ public class Recipes1_11_2 {
|
||||
recipes.add(RecipeInfo.smelting(Items.RED_GLAZED_TERRACOTTA, Items.RED_TERRACOTTA, 0.1F));
|
||||
recipes.add(RecipeInfo.smelting(Items.BLACK_GLAZED_TERRACOTTA, Items.BLACK_TERRACOTTA, 0.1F));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_11_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_11_1to1_11_2)) {
|
||||
recipes.add(RecipeInfo.smelting(Items.IRON_NUGGET, Ingredient.ofItems(Items.CHAINMAIL_HELMET, Items.CHAINMAIL_CHESTPLATE, Items.CHAINMAIL_LEGGINGS, Items.CHAINMAIL_BOOTS, Items.IRON_PICKAXE, Items.IRON_SHOVEL, Items.IRON_AXE, Items.IRON_HOE, Items.IRON_SWORD, Items.IRON_HELMET, Items.IRON_CHESTPLATE, Items.IRON_LEGGINGS, Items.IRON_BOOTS, Items.IRON_HORSE_ARMOR), 0.1F));
|
||||
recipes.add(RecipeInfo.smelting(Items.GOLD_NUGGET, Ingredient.ofItems(Items.GOLDEN_PICKAXE, Items.GOLDEN_SHOVEL, Items.GOLDEN_AXE, Items.GOLDEN_HOE, Items.GOLDEN_SWORD, Items.GOLDEN_HELMET, Items.GOLDEN_CHESTPLATE, Items.GOLDEN_LEGGINGS, Items.GOLDEN_BOOTS, Items.GOLDEN_HORSE_ARMOR), 0.1F));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_9)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_9)) {
|
||||
recipes.add(RecipeInfo.smelting(Items.POPPED_CHORUS_FRUIT, Items.CHORUS_FRUIT, 0.1F));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(ProtocolVersion.v1_7_2)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_7_2tor1_7_5)) {
|
||||
recipes.add(RecipeInfo.smelting(Items.COOKED_RABBIT, Items.RABBIT, 0.35F));
|
||||
recipes.add(RecipeInfo.smelting(Items.COOKED_MUTTON, Items.MUTTON, 0.35F));
|
||||
recipes.add(RecipeInfo.smelting(Items.CRACKED_STONE_BRICKS, Items.STONE_BRICKS, 0.1F));
|
||||
recipes.add(RecipeInfo.smelting(Items.SPONGE, Items.WET_SPONGE, 0.15F));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_6_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_6_1)) {
|
||||
recipes.add(RecipeInfo.smelting(Items.TERRACOTTA, Items.CLAY, 0.35F));
|
||||
recipes.add(RecipeInfo.smelting(Items.COOKED_SALMON, Items.SALMON, 0.35F));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_5tor1_5_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_5tor1_5_1)) {
|
||||
recipes.add(RecipeInfo.smelting(Items.NETHER_BRICK, Items.NETHERRACK, 0.1F));
|
||||
recipes.add(RecipeInfo.smelting(Items.QUARTZ, Items.NETHER_QUARTZ_ORE, 0.2F));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_4_2)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_4_2)) {
|
||||
recipes.add(RecipeInfo.smelting(Items.BAKED_POTATO, Items.POTATO, 0.35F));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_3_1tor1_3_2)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_3_1tor1_3_2)) {
|
||||
recipes.add(RecipeInfo.smelting(Items.EMERALD, Items.EMERALD_ORE, 1.0F));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.r1_0_0tor1_0_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.r1_0_0tor1_0_1)) {
|
||||
recipes.add(RecipeInfo.smelting(Items.COAL, Items.COAL_ORE, 0.1F));
|
||||
recipes.add(RecipeInfo.smelting(Items.REDSTONE, Items.REDSTONE_ORE, 0.7F));
|
||||
recipes.add(RecipeInfo.smelting(Items.LAPIS_LAZULI, Items.LAPIS_ORE, 0.2F));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_8tob1_8_1)) {
|
||||
recipes.add(RecipeInfo.smelting(Items.COOKED_CHICKEN, Items.CHICKEN, 0.35F));
|
||||
recipes.add(RecipeInfo.smelting(Items.COOKED_BEEF, Items.BEEF, 0.35F));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.b1_2_0tob1_2_2)) {
|
||||
recipes.add(RecipeInfo.smelting(Items.CHARCOAL, Ingredient.ofItems(Items.OAK_LOG, Items.SPRUCE_LOG, Items.BIRCH_LOG, Items.JUNGLE_LOG, Items.ACACIA_LOG, Items.DARK_OAK_LOG), 0.15F));
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.b1_2_0tob1_2_2)) {
|
||||
recipes.add(RecipeInfo.smelting(Items.CHARCOAL, Ingredient.fromTag(ItemTags.LOGS), 0.15F));
|
||||
recipes.add(RecipeInfo.smelting(Items.GREEN_DYE, Items.CACTUS, 0.2F));
|
||||
}
|
||||
if (targetVersion.newerThanOrEqualTo(LegacyProtocolVersion.a1_2_0toa1_2_1_1)) {
|
||||
if (targetVersion.isNewerThanOrEqualTo(VersionEnum.a1_2_0toa1_2_1_1)) {
|
||||
recipes.add(RecipeInfo.smelting(Items.COOKED_COD, Items.COD, 0.35F));
|
||||
}
|
||||
|
||||
@ -727,15 +702,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 = 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
|
||||
final var result = network.getRecipeManager()
|
||||
.getFirstMatch(RecipeType.CRAFTING, inventory, world) // Get the first matching recipe
|
||||
.map(recipe -> recipe.value().craft(inventory, network.getRegistryManager())) // Craft the recipe to get the result
|
||||
.orElse(ItemStack.EMPTY); // If there is no recipe, set the result to air
|
||||
|
||||
// Update the result slot
|
||||
|
@ -1,93 +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.data.recipe;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.ShulkerBoxBlock;
|
||||
import net.minecraft.item.DyeItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.recipe.RecipeSerializer;
|
||||
import net.minecraft.recipe.SpecialCraftingRecipe;
|
||||
import net.minecraft.recipe.book.CraftingRecipeCategory;
|
||||
import net.minecraft.recipe.input.CraftingRecipeInput;
|
||||
import net.minecraft.registry.RegistryWrapper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ShulkerBoxColoringRecipe extends SpecialCraftingRecipe {
|
||||
|
||||
public static final RecipeSerializer<ShulkerBoxColoringRecipe> SERIALIZER = new SpecialRecipeSerializer<>(ShulkerBoxColoringRecipe::new);
|
||||
|
||||
public ShulkerBoxColoringRecipe(CraftingRecipeCategory craftingRecipeCategory) {
|
||||
super(craftingRecipeCategory);
|
||||
}
|
||||
|
||||
public boolean matches(CraftingRecipeInput input, World world) {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
for (int k = 0; k < input.size(); k++) {
|
||||
ItemStack stack = input.getStackInSlot(k);
|
||||
if (!stack.isEmpty()) {
|
||||
if (Block.getBlockFromItem(stack.getItem()) instanceof ShulkerBoxBlock) {
|
||||
i++;
|
||||
} else {
|
||||
if (!(stack.getItem() instanceof DyeItem)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
if (j > 1 || i > 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i == 1 && j == 1;
|
||||
}
|
||||
|
||||
public ItemStack craft(CraftingRecipeInput input, RegistryWrapper.WrapperLookup wrapperLookup) {
|
||||
ItemStack result = ItemStack.EMPTY;
|
||||
DyeItem dyeItem = (DyeItem) Items.WHITE_DYE;
|
||||
|
||||
for (int i = 0; i < input.size(); i++) {
|
||||
ItemStack stack = input.getStackInSlot(i);
|
||||
if (!stack.isEmpty()) {
|
||||
Item item = stack.getItem();
|
||||
if (Block.getBlockFromItem(item) instanceof ShulkerBoxBlock) {
|
||||
result = stack;
|
||||
} else if (item instanceof DyeItem) {
|
||||
dyeItem = (DyeItem) item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.copyComponentsToNewStack(ShulkerBoxBlock.get(dyeItem.getColor()), 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeSerializer<ShulkerBoxColoringRecipe> getSerializer() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
}
|
@ -17,23 +17,25 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned.visual;
|
||||
package de.florianmichael.viafabricplus.fixes.entity;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.client.model.*;
|
||||
import net.minecraft.client.render.entity.model.EntityModel;
|
||||
import net.minecraft.client.render.entity.model.CompositeEntityModel;
|
||||
import net.minecraft.client.render.entity.model.EntityModelLayer;
|
||||
import net.minecraft.client.render.entity.state.BoatEntityRenderState;
|
||||
import net.minecraft.entity.vehicle.BoatEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
/**
|
||||
* Model for boats in 1.8 and lower.
|
||||
*/
|
||||
public class BoatModel1_8 extends EntityModel<BoatEntityRenderState> {
|
||||
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) {
|
||||
super(root);
|
||||
this.parts = ImmutableList.of(root.getChild("bottom"), root.getChild("back"), root.getChild("front"), root.getChild("right"), root.getChild("left"));
|
||||
}
|
||||
|
||||
public static TexturedModelData getTexturedModelData() {
|
||||
@ -52,7 +54,12 @@ public class BoatModel1_8 extends EntityModel<BoatEntityRenderState> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAngles(BoatEntityRenderState state) {
|
||||
public Iterable<ModelPart> getParts() {
|
||||
return parts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAngles(BoatEntity entity, float limbAngle, float limbDistance, float animationProgress, float headYaw, float headPitch) {
|
||||
}
|
||||
|
||||
}
|
@ -17,17 +17,15 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned.visual;
|
||||
package de.florianmichael.viafabricplus.fixes.entity;
|
||||
|
||||
import net.minecraft.client.render.OverlayTexture;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.entity.AbstractBoatEntityRenderer;
|
||||
import net.minecraft.client.render.entity.EntityRenderer;
|
||||
import net.minecraft.client.render.entity.EntityRendererFactory;
|
||||
import net.minecraft.client.render.entity.model.EntityModel;
|
||||
import net.minecraft.client.render.entity.state.BoatEntityRenderState;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.vehicle.BoatEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.RotationAxis;
|
||||
@ -35,9 +33,9 @@ import net.minecraft.util.math.RotationAxis;
|
||||
/**
|
||||
* Renderer for boats in 1.8 and lower.
|
||||
*/
|
||||
public class BoatRenderer1_8 extends AbstractBoatEntityRenderer {
|
||||
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) {
|
||||
@ -47,31 +45,33 @@ public class BoatRenderer1_8 extends AbstractBoatEntityRenderer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected EntityModel<BoatEntityRenderState> getModel() {
|
||||
return this.model;
|
||||
public Identifier getTexture(BoatEntity entity) {
|
||||
return TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RenderLayer getRenderLayer() {
|
||||
return this.model.getLayer(TEXTURE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(BoatEntityRenderState state, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) {
|
||||
public void render(BoatEntity entity, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) {
|
||||
matrices.push();
|
||||
matrices.translate(0, 0.25, 0);
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180 - state.yaw));
|
||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180 - yaw));
|
||||
|
||||
if (state.damageWobbleTicks > 0) {
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(MathHelper.sin(state.damageWobbleTicks) * state.damageWobbleTicks * state.damageWobbleStrength / 10 * state.damageWobbleSide));
|
||||
float damageWobbleTicks = entity.getDamageWobbleTicks() - tickDelta;
|
||||
float damageWobbleStrength = entity.getDamageWobbleStrength() - tickDelta;
|
||||
|
||||
if (damageWobbleStrength < 0) {
|
||||
damageWobbleStrength = 0;
|
||||
}
|
||||
if (damageWobbleTicks > 0) {
|
||||
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(MathHelper.sin(damageWobbleTicks) * damageWobbleTicks * damageWobbleStrength / 10 * entity.getDamageWobbleSide()));
|
||||
}
|
||||
|
||||
matrices.scale(-1, -1, 1);
|
||||
model.setAngles(state);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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.entity;
|
||||
|
||||
import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static de.florianmichael.viafabricplus.util.MapUtil.linkedHashMap;
|
||||
|
||||
/**
|
||||
* Data dump for entity dimension changes between versions.
|
||||
*/
|
||||
public class EntityDimensionReplacements {
|
||||
|
||||
/**
|
||||
* A map of entity types to a map of versions to dimensions.
|
||||
*/
|
||||
private static final Map<EntityType<?>, Map<VersionEnum, EntityDimensions>> ENTITY_DIMENSIONS = linkedHashMap(
|
||||
EntityType.WITHER, linkedHashMap(
|
||||
VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.9F, 4.0F),
|
||||
VersionEnum.r1_8, EntityType.WITHER.getDimensions()
|
||||
),
|
||||
EntityType.SILVERFISH, linkedHashMap(
|
||||
VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.3F, 0.7F),
|
||||
VersionEnum.r1_8, EntityType.SILVERFISH.getDimensions()
|
||||
),
|
||||
EntityType.SNOW_GOLEM, linkedHashMap(
|
||||
VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.4F, 1.8F),
|
||||
VersionEnum.r1_8, EntityType.SNOW_GOLEM.getDimensions()
|
||||
),
|
||||
EntityType.ZOMBIE, linkedHashMap(
|
||||
VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.6F, 1.8F),
|
||||
VersionEnum.r1_8, EntityDimensions.fixed(EntityType.ZOMBIE.getDimensions().width, EntityType.ZOMBIE.getDimensions().height),
|
||||
VersionEnum.r1_9, EntityType.ZOMBIE.getDimensions()
|
||||
),
|
||||
EntityType.CHICKEN, linkedHashMap(
|
||||
VersionEnum.b1_7tob1_7_3, EntityDimensions.changing(0.3F, 0.4F),
|
||||
VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.3F, 0.7F),
|
||||
VersionEnum.r1_8, EntityType.CHICKEN.getDimensions()
|
||||
),
|
||||
EntityType.SHEEP, linkedHashMap(
|
||||
VersionEnum.c0_28toc0_30, EntityDimensions.changing(1.4F, 1.72F),
|
||||
VersionEnum.a1_0_15, EntityType.SHEEP.getDimensions()
|
||||
),
|
||||
EntityType.OCELOT, linkedHashMap(
|
||||
VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.6F, 0.8F),
|
||||
VersionEnum.r1_8, EntityType.OCELOT.getDimensions()
|
||||
),
|
||||
EntityType.BOAT, linkedHashMap(
|
||||
VersionEnum.r1_8, EntityDimensions.changing(1.5F, 0.6F),
|
||||
VersionEnum.r1_9, EntityType.BOAT.getDimensions()
|
||||
),
|
||||
EntityType.CREEPER, linkedHashMap(
|
||||
VersionEnum.r1_8, EntityDimensions.changing(0.6F, 1.8F),
|
||||
VersionEnum.r1_9, EntityType.CREEPER.getDimensions()
|
||||
),
|
||||
EntityType.IRON_GOLEM, linkedHashMap(
|
||||
VersionEnum.r1_8, EntityDimensions.changing(1.4F, 2.9F),
|
||||
VersionEnum.r1_9, EntityType.IRON_GOLEM.getDimensions()
|
||||
),
|
||||
EntityType.SKELETON, linkedHashMap(
|
||||
VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.6F, 1.8F),
|
||||
VersionEnum.r1_8, EntityDimensions.changing(0.6F, 1.95F),
|
||||
VersionEnum.r1_9, EntityType.SKELETON.getDimensions()
|
||||
),
|
||||
EntityType.WITHER_SKELETON, linkedHashMap(
|
||||
VersionEnum.r1_4_6tor1_4_7, EntityDimensions.changing(0.72F, 2.16F),
|
||||
VersionEnum.r1_7_6tor1_7_10, EntityDimensions.changing(0.72F, 2.34F),
|
||||
VersionEnum.r1_8, EntityDimensions.changing(0.72F, 2.535F),
|
||||
VersionEnum.r1_9, EntityType.WITHER_SKELETON.getDimensions()
|
||||
),
|
||||
EntityType.COW, linkedHashMap(
|
||||
VersionEnum.r1_8, EntityDimensions.changing(0.9F, 1.3F),
|
||||
VersionEnum.r1_9, EntityType.COW.getDimensions()
|
||||
),
|
||||
EntityType.HORSE, linkedHashMap(
|
||||
VersionEnum.r1_8, EntityDimensions.changing(1.4F, 1.6F),
|
||||
VersionEnum.r1_9, EntityType.HORSE.getDimensions()
|
||||
),
|
||||
EntityType.MOOSHROOM, linkedHashMap(
|
||||
VersionEnum.r1_8, EntityDimensions.changing(0.9F, 1.3F),
|
||||
VersionEnum.r1_9, EntityType.MOOSHROOM.getDimensions()
|
||||
),
|
||||
EntityType.RABBIT, linkedHashMap(
|
||||
VersionEnum.r1_8, EntityDimensions.changing(0.6F, 0.7F),
|
||||
VersionEnum.r1_9, EntityType.RABBIT.getDimensions()
|
||||
),
|
||||
EntityType.SQUID, linkedHashMap(
|
||||
VersionEnum.r1_8, EntityDimensions.changing(0.95F, 0.95F),
|
||||
VersionEnum.r1_9, EntityType.SQUID.getDimensions()
|
||||
),
|
||||
EntityType.VILLAGER, linkedHashMap(
|
||||
VersionEnum.r1_8, EntityDimensions.changing(0.6F, 1.8F),
|
||||
VersionEnum.r1_9, EntityType.VILLAGER.getDimensions()
|
||||
),
|
||||
EntityType.WOLF, linkedHashMap(
|
||||
VersionEnum.r1_1, EntityDimensions.changing(0.8F, 0.8F),
|
||||
VersionEnum.r1_8, EntityDimensions.changing(0.6F, 0.8F),
|
||||
VersionEnum.r1_9, EntityType.WOLF.getDimensions()
|
||||
),
|
||||
EntityType.DRAGON_FIREBALL, linkedHashMap(
|
||||
VersionEnum.r1_10, EntityDimensions.changing(0.3125F, 0.3125F),
|
||||
VersionEnum.r1_11, EntityType.DRAGON_FIREBALL.getDimensions()
|
||||
),
|
||||
EntityType.LEASH_KNOT, linkedHashMap(
|
||||
VersionEnum.r1_16_4tor1_16_5, EntityDimensions.changing(0.5F, 0.5F),
|
||||
VersionEnum.r1_17, EntityType.LEASH_KNOT.getDimensions()
|
||||
),
|
||||
EntityType.SLIME, linkedHashMap(
|
||||
VersionEnum.r1_13_2, EntityDimensions.changing(2F, 2F),
|
||||
VersionEnum.r1_14, EntityType.SLIME.getDimensions()
|
||||
),
|
||||
EntityType.MAGMA_CUBE, linkedHashMap(
|
||||
VersionEnum.r1_13_2, EntityDimensions.changing(2F, 2F),
|
||||
VersionEnum.r1_14, EntityType.MAGMA_CUBE.getDimensions()
|
||||
),
|
||||
EntityType.ARROW, linkedHashMap(
|
||||
VersionEnum.c0_28toc0_30, EntityDimensions.changing(0.3F, 0.5F),
|
||||
VersionEnum.a1_0_15, EntityType.ARROW.getDimensions()
|
||||
)
|
||||
);
|
||||
|
||||
static {
|
||||
ChangeProtocolVersionCallback.EVENT.register((oldVersion, newVersion) -> MinecraftClient.getInstance().execute(() -> ENTITY_DIMENSIONS.forEach((entityType, dimensionMap) -> {
|
||||
for (Map.Entry<VersionEnum, EntityDimensions> entry : dimensionMap.entrySet()) {
|
||||
final VersionEnum version = entry.getKey();
|
||||
final EntityDimensions dimensions = entry.getValue();
|
||||
if (oldVersion.isNewerThan(version) && newVersion.isOlderThanOrEqualTo(version)) {
|
||||
entityType.dimensions = dimensions;
|
||||
break;
|
||||
}
|
||||
if (newVersion.isNewerThanOrEqualTo(version) && oldVersion.isOlderThanOrEqualTo(version)) {
|
||||
entityType.dimensions = dimensions;
|
||||
}
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
// Loads the class and triggers the static initializer.
|
||||
}
|
||||
|
||||
/**
|
||||
* @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<VersionEnum, EntityDimensions> getEntityDimensions(final EntityType<?> entityType) {
|
||||
if (!ENTITY_DIMENSIONS.containsKey(entityType)) {
|
||||
return null;
|
||||
}
|
||||
return Collections.unmodifiableMap(ENTITY_DIMENSIONS.get(entityType));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param entityType The {@link EntityType} to get the dimensions for.
|
||||
* @param version The {@link VersionEnum} to get the dimensions for.
|
||||
* @return The closest dimensions for the given {@link EntityType} and {@link VersionEnum} or null if there are none.
|
||||
*/
|
||||
public static EntityDimensions getEntityDimensions(final EntityType<?> entityType, final VersionEnum version) {
|
||||
final Map<VersionEnum, EntityDimensions> dimensionMap = getEntityDimensions(entityType);
|
||||
if (dimensionMap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
EntityDimensions closestDimensions = null;
|
||||
VersionEnum closestVersion = null;
|
||||
|
||||
for (Map.Entry<VersionEnum, EntityDimensions> entry : dimensionMap.entrySet()) {
|
||||
final var currentVersion = entry.getKey();
|
||||
final var currentDimensions = entry.getValue();
|
||||
|
||||
if (currentVersion == version) { // If the version is exactly the same, return the dimensions
|
||||
return currentDimensions;
|
||||
}
|
||||
|
||||
// If the current version is closer to the version you are looking for
|
||||
if (closestVersion == null || Math.abs(version.ordinal() - currentVersion.ordinal()) < Math.abs(version.ordinal() - closestVersion.ordinal())) {
|
||||
closestVersion = currentVersion;
|
||||
closestDimensions = currentDimensions;
|
||||
}
|
||||
}
|
||||
|
||||
return closestDimensions;
|
||||
}
|
||||
|
||||
}
|
@ -17,10 +17,9 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned.visual;
|
||||
package de.florianmichael.viafabricplus.fixes.entity;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.EntityPose;
|
||||
@ -30,12 +29,12 @@ import net.minecraft.entity.decoration.ArmorStandEntity;
|
||||
import net.minecraft.entity.mob.*;
|
||||
import net.minecraft.entity.passive.*;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.vehicle.AbstractBoatEntity;
|
||||
import net.minecraft.entity.vehicle.AbstractChestBoatEntity;
|
||||
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 net.raphimc.vialoader.util.VersionEnum;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
* Minecraft 1.20.2 changed the calculation of the mounted height offset for all entities, this class contains the old
|
||||
@ -50,28 +49,28 @@ 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 AbstractBoatEntity abstractBoatEntity) {
|
||||
if (!abstractBoatEntity.hasPassenger(passenger)) return Vec3d.ZERO;
|
||||
if (entity instanceof BoatEntity boatEntity) {
|
||||
if (!boatEntity.hasPassenger(passenger)) return new Vector3f();
|
||||
|
||||
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
|
||||
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
|
||||
yOffset = -0.3F;
|
||||
final double xOffset = MathHelper.cos(abstractBoatEntity.getYaw() * MathHelper.PI / 180F);
|
||||
final double zOffset = MathHelper.sin(abstractBoatEntity.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 (abstractBoatEntity.isRemoved()) {
|
||||
if (boatEntity.isRemoved()) {
|
||||
yOffset = 0.01F;
|
||||
} else {
|
||||
yOffset = abstractBoatEntity.getType() == EntityType.BAMBOO_RAFT || abstractBoatEntity.getType() == EntityType.BAMBOO_CHEST_RAFT ? 0.25F : -0.1F;
|
||||
yOffset = boatEntity.getVariant() == BoatEntity.Type.BAMBOO ? 0.25F : -0.1F;
|
||||
}
|
||||
|
||||
double xOffset = abstractBoatEntity instanceof AbstractChestBoatEntity ? 0.15F : 0F;
|
||||
if (abstractBoatEntity.getPassengerList().size() > 1) {
|
||||
final int idx = abstractBoatEntity.getPassengerList().indexOf(passenger);
|
||||
float xOffset = boatEntity instanceof ChestBoatEntity ? 0.15F : 0F;
|
||||
if (boatEntity.getPassengerList().size() > 1) {
|
||||
final int idx = boatEntity.getPassengerList().indexOf(passenger);
|
||||
if (idx == 0) {
|
||||
xOffset = 0.2F;
|
||||
} else {
|
||||
@ -81,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,12 +133,12 @@ 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);
|
||||
if (abstractHorseEntity.lastAngryAnimationProgress > 0.0f) {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,7 +149,7 @@ public class EntityRidingOffsetsPre1_20_2 {
|
||||
*/
|
||||
public static double getHeightOffset(final Entity entity) {
|
||||
if (entity instanceof AllayEntity || entity instanceof VexEntity) {
|
||||
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_19_1)) {
|
||||
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_19_1tor1_19_2)) {
|
||||
return 0D;
|
||||
} else {
|
||||
return 0.4D;
|
@ -17,40 +17,28 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned.visual;
|
||||
package de.florianmichael.viafabricplus.fixes.particle;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
|
||||
import net.fabricmc.fabric.api.particle.v1.FabricParticleTypes;
|
||||
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;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public class FootStepParticle1_12_2 extends SpriteBillboardParticle {
|
||||
public class FootStepParticle extends SpriteBillboardParticle {
|
||||
|
||||
public static final Identifier ID = Identifier.of("viafabricplus", "footstep");
|
||||
public static int RAW_ID;
|
||||
public static int 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);
|
||||
}
|
||||
|
||||
protected FootStepParticle1_12_2(ClientWorld clientWorld, double x, double y, double z) {
|
||||
protected FootStepParticle(ClientWorld clientWorld, double x, double y, double z) {
|
||||
super(clientWorld, x, y, z);
|
||||
|
||||
this.scale = 0.125F;
|
||||
@ -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, FootStepParticle.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,12 +95,12 @@ 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) {
|
||||
if (ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_12_2)) {
|
||||
public Particle createParticle(DefaultParticleType parameters, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
|
||||
if (ProtocolHack.getTargetVersion().isNewerThan(VersionEnum.r1_12_2)) {
|
||||
throw new UnsupportedOperationException("FootStepParticle is not supported on versions newer than 1.12.2");
|
||||
}
|
||||
|
||||
final FootStepParticle1_12_2 particle = new FootStepParticle1_12_2(world, x, y, z);
|
||||
final FootStepParticle particle = new FootStepParticle(world, x, y, z);
|
||||
particle.setSprite(this.spriteProvider);
|
||||
return particle;
|
||||
}
|
@ -17,10 +17,10 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned.visual;
|
||||
package de.florianmichael.viafabricplus.fixes.replacement;
|
||||
|
||||
import net.minecraft.client.font.BakedGlyph;
|
||||
import net.minecraft.client.font.Glyph;
|
||||
import net.minecraft.client.font.GlyphRenderer;
|
||||
import net.minecraft.client.font.RenderableGlyph;
|
||||
|
||||
import java.util.function.Function;
|
||||
@ -41,7 +41,7 @@ public enum BuiltinEmptyGlyph1_12_2 implements Glyph {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BakedGlyph bake(Function<RenderableGlyph, BakedGlyph> glyphRendererGetter) {
|
||||
public GlyphRenderer bake(Function<RenderableGlyph, GlyphRenderer> glyphRendererGetter) {
|
||||
return glyphRendererGetter.apply(new RenderableGlyph() {
|
||||
|
||||
@Override
|
@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned;
|
||||
package de.florianmichael.viafabricplus.fixes.replacement;
|
||||
|
||||
import com.mojang.authlib.yggdrasil.response.KeyPairResponse;
|
||||
|
@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.florianmichael.viafabricplus.fixes.versioned;
|
||||
package de.florianmichael.viafabricplus.fixes.replacement;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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,13 @@ 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;
|
||||
}
|
||||
|
||||
}
|
@ -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.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.MINING_EFFICIENCY).setBaseValue(efficiencyLevel * efficiencyLevel + 1);
|
||||
} else {
|
||||
player.getAttributeInstance(EntityAttributes.MINING_EFFICIENCY).setBaseValue(0);
|
||||
}
|
||||
|
||||
player.getAttributeInstance(EntityAttributes.SNEAKING_SPEED).setBaseValue(0.3F + getEquipmentLevel(Enchantments.SWIFT_SNEAK, player) * 0.15F);
|
||||
player.getAttributeInstance(EntityAttributes.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.MOVEMENT_EFFICIENCY).setBaseValue(1);
|
||||
} else {
|
||||
entity.getAttributeInstance(EntityAttributes.MOVEMENT_EFFICIENCY).setBaseValue(0);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getEquipmentLevel(final RegistryKey<Enchantment> enchantment, final LivingEntity entity) {
|
||||
final Optional<RegistryEntry.Reference<Enchantment>> enchantmentRef = entity.getWorld().getRegistryManager().getOrThrow(RegistryKeys.ENCHANTMENT).getOptional(enchantment);
|
||||
return enchantmentRef.map(e -> EnchantmentHelper.getEquipmentLevel(e, entity)).orElse(0);
|
||||
}
|
||||
|
||||
}
|
@ -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)));
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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_21to1_21_2.packet.ClientboundPackets1_21_2;
|
||||
import com.viaversion.viaversion.protocols.v1_21to1_21_2.packet.ServerboundPackets1_21_2;
|
||||
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_21_2.SET_CREATIVE_MODE_SLOT;
|
||||
}
|
||||
|
||||
public static ClientboundPacketType getCustomPayload() {
|
||||
return ClientboundPackets1_21_2.CUSTOM_PAYLOAD;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface PacketReader {
|
||||
|
||||
void read(PacketWrapper wrapper);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -20,7 +20,6 @@
|
||||
package de.florianmichael.viafabricplus.injection;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.metadata.ModMetadata;
|
||||
import net.lenni0451.reflect.stream.RStream;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
||||
@ -33,26 +32,24 @@ public class ViaFabricPlusMixinPlugin implements IMixinConfigPlugin {
|
||||
|
||||
public static final String INJECTOR_PACKAGE = "de.florianmichael.viafabricplus.injection.mixin.";
|
||||
|
||||
private static final String MC_FIXES_PACKAGE = "fixes.minecraft.";
|
||||
private static final String COMPAT_PACKAGE = "compat.";
|
||||
|
||||
public static String VFP_VERSION;
|
||||
public static String VFP_IMPL_VERSION;
|
||||
|
||||
public static boolean DASH_LOADER_PRESENT;
|
||||
public static boolean ARMOR_SKIN_PRESENT;
|
||||
public static boolean IPNEXT_PRESENT;
|
||||
public static boolean MORE_CULLING_PRESENT;
|
||||
public static boolean LITHIUM_PRESENT;
|
||||
|
||||
@Override
|
||||
public void onLoad(String mixinPackage) {
|
||||
final FabricLoader loader = FabricLoader.getInstance();
|
||||
|
||||
final ModMetadata metadata = loader.getModContainer("viafabricplus").get().getMetadata();
|
||||
VFP_VERSION = metadata.getVersion().getFriendlyString();
|
||||
VFP_IMPL_VERSION = metadata.getCustomValue("vfp:implVersion").getAsString();
|
||||
VFP_VERSION = loader.getModContainer("viafabricplus").get().getMetadata().getVersion().getFriendlyString();
|
||||
|
||||
DASH_LOADER_PRESENT = loader.isModLoaded("dashloader");
|
||||
ARMOR_SKIN_PRESENT = loader.isModLoaded("armorskin");
|
||||
IPNEXT_PRESENT = loader.isModLoaded("inventoryprofilesnext");
|
||||
MORE_CULLING_PRESENT = loader.isModLoaded("moreculling");
|
||||
LITHIUM_PRESENT = loader.isModLoaded("lithium");
|
||||
|
||||
// Force unload some FabricAPI mixins because FabricAPI overwrites some of the elytra code
|
||||
final Set<String> loadedMixins = RStream.of("org.spongepowered.asm.mixin.transformer.MixinConfig").fields().by("globalMixinList").get();
|
||||
@ -68,11 +65,17 @@ public class ViaFabricPlusMixinPlugin implements IMixinConfigPlugin {
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||
return switch (mixinClassName) {
|
||||
case INJECTOR_PACKAGE + COMPAT_PACKAGE + "ipnext.MixinAutoRefillHandler_ItemSlotMonitor" -> IPNEXT_PRESENT;
|
||||
case INJECTOR_PACKAGE + COMPAT_PACKAGE + "lithium.MixinEntity" -> LITHIUM_PRESENT;
|
||||
default -> true;
|
||||
};
|
||||
if (mixinClassName.equals(INJECTOR_PACKAGE + MC_FIXES_PACKAGE + "MixinFontStorage")) {
|
||||
return !DASH_LOADER_PRESENT;
|
||||
}
|
||||
if (mixinClassName.equals(INJECTOR_PACKAGE + MC_FIXES_PACKAGE + "MixinInGameHud")) {
|
||||
return !ARMOR_SKIN_PRESENT;
|
||||
}
|
||||
if (mixinClassName.equals(INJECTOR_PACKAGE + COMPAT_PACKAGE + "ipnext.MixinAutoRefillHandler_ItemSlotMonitor")) {
|
||||
return IPNEXT_PRESENT;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -20,14 +20,14 @@
|
||||
package de.florianmichael.viafabricplus.injection.access;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
|
||||
public interface IClientConnection {
|
||||
|
||||
void viaFabricPlus$setupPreNettyDecryption();
|
||||
|
||||
ProtocolVersion viaFabricPlus$getTargetVersion();
|
||||
void viaFabricPlus$setTargetVersion(final ProtocolVersion serverVersion);
|
||||
VersionEnum viaFabricPlus$getTargetVersion();
|
||||
void viaFabricPlus$setTargetVersion(final VersionEnum serverVersion);
|
||||
|
||||
UserConnection viaFabricPlus$getUserConnection();
|
||||
void viaFabricPlus$setUserConnection(final UserConnection userConnection);
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.injection.access;
|
||||
|
||||
import de.florianmichael.viafabricplus.fixes.versioned.ClientPlayerInteractionManager1_18_2;
|
||||
import de.florianmichael.viafabricplus.fixes.ClientPlayerInteractionManager1_18_2;
|
||||
|
||||
public interface IClientPlayerInteractionManager {
|
||||
|
||||
|
@ -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();
|
||||
|
||||
}
|
||||
|
@ -19,10 +19,12 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.injection.access;
|
||||
|
||||
import net.minecraft.text.Text;
|
||||
public interface IItemStack {
|
||||
|
||||
public interface IConfirmScreen {
|
||||
boolean viaFabricPlus$has1_10ViaFabricPlusTag();
|
||||
|
||||
void viaFabricPlus$setMessage(final Text message);
|
||||
int viaFabricPlus$get1_10Count();
|
||||
|
||||
void viaFabricPlus$set1_10Count(final int count);
|
||||
|
||||
}
|
@ -1,29 +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;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
|
||||
public interface IMultiValueDebugSampleLogImpl {
|
||||
|
||||
ProtocolVersion viaFabricPlus$getForcedVersion();
|
||||
void viaFabricPlus$setForcedVersion(final ProtocolVersion version);
|
||||
|
||||
}
|
@ -19,8 +19,11 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.injection.access;
|
||||
|
||||
public interface IPlayerListHud {
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
|
||||
void viaFabricPlus$setMaxPlayers(final int maxPlayers);
|
||||
public interface IPerformanceLog {
|
||||
|
||||
VersionEnum viaFabricPlus$getForcedVersion();
|
||||
void viaFabricPlus$setForcedVersion(final VersionEnum version);
|
||||
|
||||
}
|
@ -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();
|
||||
|
||||
}
|
@ -19,17 +19,17 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.injection.access;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
|
||||
public interface IServerInfo {
|
||||
|
||||
ProtocolVersion viaFabricPlus$forcedVersion();
|
||||
void viaFabricPlus$forceVersion(final ProtocolVersion version);
|
||||
VersionEnum viaFabricPlus$forcedVersion();
|
||||
void viaFabricPlus$forceVersion(final VersionEnum version);
|
||||
|
||||
boolean viaFabricPlus$passedDirectConnectScreen();
|
||||
void viaFabricPlus$passDirectConnectScreen(final boolean state);
|
||||
void viaFabricPlus$passDirectConnectScreen();
|
||||
|
||||
ProtocolVersion viaFabricPlus$translatingVersion();
|
||||
void viaFabricPlus$setTranslatingVersion(final ProtocolVersion version);
|
||||
VersionEnum viaFabricPlus$translatingVersion();
|
||||
void viaFabricPlus$setTranslatingVersion(final VersionEnum version);
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public abstract class MixinMain {
|
||||
@Inject(method = "main", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Util;startTimerHack()V"))
|
||||
private static void bootstrap(CallbackInfo ci) {
|
||||
LoadCallback.EVENT.invoker().onLoad(LoadCallback.State.PRE);
|
||||
ViaFabricPlus.global().init();
|
||||
ViaFabricPlus.global().bootstrap();
|
||||
LoadCallback.EVENT.invoker().onLoad(LoadCallback.State.POST);
|
||||
}
|
||||
|
||||
|
@ -19,16 +19,13 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.injection.mixin.base.connect;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
|
||||
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.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.protocoltranslator.ProtocolTranslator;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.netty.ViaFabricPlusVLLegacyPipeline;
|
||||
import de.florianmichael.viafabricplus.injection.access.IPerformanceLog;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import de.florianmichael.viafabricplus.protocolhack.netty.ViaFabricPlusVLLegacyPipeline;
|
||||
import de.florianmichael.viafabricplus.protocolhack.util.VersionEnumExtension;
|
||||
import io.netty.bootstrap.AbstractBootstrap;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.*;
|
||||
@ -38,15 +35,13 @@ 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.raphimc.viabedrock.api.BedrockProtocolVersion;
|
||||
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
|
||||
import net.minecraft.util.profiler.PerformanceLog;
|
||||
import net.raphimc.vialoader.netty.CompressionReorderEvent;
|
||||
import net.raphimc.vialoader.netty.VLLegacyPipeline;
|
||||
import net.raphimc.vialoader.netty.VLPipeline;
|
||||
import net.raphimc.vialoader.netty.viabedrock.PingEncapsulationCodec;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
import org.cloudburstmc.netty.channel.raknet.RakChannelFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@ -78,7 +73,7 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler<
|
||||
private UserConnection viaFabricPlus$userConnection;
|
||||
|
||||
@Unique
|
||||
private ProtocolVersion viaFabricPlus$serverVersion;
|
||||
private VersionEnum viaFabricPlus$serverVersion;
|
||||
|
||||
@Unique
|
||||
private Cipher viaFabricPlus$decryptionCipher;
|
||||
@ -91,13 +86,13 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler<
|
||||
|
||||
@Inject(method = "setupEncryption", at = @At("HEAD"), cancellable = true)
|
||||
private void storeDecryptionCipher(Cipher decryptionCipher, Cipher encryptionCipher, CallbackInfo ci) {
|
||||
if (this.viaFabricPlus$serverVersion != null /* This happens when opening a lan server and people are joining */ && this.viaFabricPlus$serverVersion.olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
|
||||
if (this.viaFabricPlus$serverVersion != null /* This happens when opening a lan server and people are joining */ && this.viaFabricPlus$serverVersion.isOlderThanOrEqualTo(VersionEnum.r1_6_4)) {
|
||||
// Minecraft's encryption code is bad for us, we need to reorder the pipeline
|
||||
ci.cancel();
|
||||
|
||||
// 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,77 +101,88 @@ 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));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
|
||||
super.channelRegistered(ctx);
|
||||
if (BedrockProtocolVersion.bedrockLatest.equals(this.viaFabricPlus$serverVersion)) { // Call channelActive manually when the channel is registered
|
||||
if (VersionEnum.bedrockLatest.equals(this.viaFabricPlus$serverVersion)) {
|
||||
// Call channelActive manually when the channel is registered
|
||||
this.channelActive(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@WrapWithCondition(method = "channelActive", at = @At(value = "INVOKE", target = "Lio/netty/channel/SimpleChannelInboundHandler;channelActive(Lio/netty/channel/ChannelHandlerContext;)V", remap = false))
|
||||
private boolean dontCallChannelActiveTwice(SimpleChannelInboundHandler<Packet<?>> instance, ChannelHandlerContext channelHandlerContext) {
|
||||
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) {
|
||||
// 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());
|
||||
@Redirect(method = "channelActive", at = @At(value = "INVOKE", target = "Lio/netty/channel/SimpleChannelInboundHandler;channelActive(Lio/netty/channel/ChannelHandlerContext;)V"), remap = false)
|
||||
private void dontCallChannelActive(SimpleChannelInboundHandler<Packet<?>> instance, ChannelHandlerContext ctx) throws Exception {
|
||||
if (!VersionEnum.bedrockLatest.equals(this.viaFabricPlus$serverVersion)) { // Don't call channelActive twice
|
||||
super.channelActive(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@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) {
|
||||
// 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;
|
||||
@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 IPerformanceLog mixinPerformanceLog && mixinPerformanceLog.viaFabricPlus$getForcedVersion() != null) {
|
||||
((IClientConnection) clientConnection).viaFabricPlus$setTargetVersion(mixinPerformanceLog.viaFabricPlus$getForcedVersion());
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(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 void dontSetPerformanceLog(ClientConnection instance, PerformanceLog performanceLog) {
|
||||
// Since the PerformanceLog is never null due to our changes, we need to restore vanilla behavior
|
||||
if (performanceLog instanceof IPerformanceLog mixinPerformanceLog && mixinPerformanceLog.viaFabricPlus$getForcedVersion() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
instance.resetPacketSizeLog(performanceLog);
|
||||
}
|
||||
|
||||
@Inject(method = "connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/network/ClientConnection;)Lio/netty/channel/ChannelFuture;", at = @At("HEAD"))
|
||||
private static void setTargetVersion(InetSocketAddress address, boolean useEpoll, ClientConnection connection, CallbackInfoReturnable<ChannelFuture> cir) {
|
||||
ProtocolVersion targetVersion = ((IClientConnection) connection).viaFabricPlus$getTargetVersion();
|
||||
VersionEnum targetVersion = ((IClientConnection) connection).viaFabricPlus$getTargetVersion();
|
||||
if (targetVersion == null) { // No server specific override
|
||||
targetVersion = ProtocolTranslator.getTargetVersion();
|
||||
targetVersion = ProtocolHack.getTargetVersion();
|
||||
}
|
||||
if (targetVersion == ProtocolTranslator.AUTO_DETECT_PROTOCOL) { // Auto-detect enabled (when pinging always use native version). Auto-detect is resolved in ConnectScreen mixin
|
||||
targetVersion = ProtocolTranslator.NATIVE_VERSION;
|
||||
if (targetVersion == VersionEnumExtension.AUTO_DETECT) { // Auto-detect enabled (when pinging always use native version). Auto-detect is resolved in ConnectScreen mixin
|
||||
targetVersion = ProtocolHack.NATIVE_VERSION;
|
||||
}
|
||||
|
||||
((IClientConnection) connection).viaFabricPlus$setTargetVersion(targetVersion);
|
||||
}
|
||||
|
||||
@WrapOperation(method = "connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/network/ClientConnection;)Lio/netty/channel/ChannelFuture;", at = @At(value = "INVOKE", target = "Lio/netty/bootstrap/Bootstrap;channel(Ljava/lang/Class;)Lio/netty/bootstrap/AbstractBootstrap;", remap = false))
|
||||
private static AbstractBootstrap<?, ?> useRakNetChannelFactory(Bootstrap instance, Class<? extends Channel> channelTypeClass, Operation<AbstractBootstrap<Bootstrap, Channel>> original, @Local(argsOnly = true) ClientConnection clientConnection) {
|
||||
if (BedrockProtocolVersion.bedrockLatest.equals(((IClientConnection) clientConnection).viaFabricPlus$getTargetVersion())) {
|
||||
return instance.channelFactory(channelTypeClass == EpollSocketChannel.class ? RakChannelFactory.client(EpollDatagramChannel.class) : RakChannelFactory.client(NioDatagramChannel.class));
|
||||
} else {
|
||||
return original.call(instance, channelTypeClass);
|
||||
@Redirect(method = "connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/network/ClientConnection;)Lio/netty/channel/ChannelFuture;", at = @At(value = "INVOKE", target = "Lio/netty/bootstrap/Bootstrap;channel(Ljava/lang/Class;)Lio/netty/bootstrap/AbstractBootstrap;", remap = false))
|
||||
private static AbstractBootstrap<?, ?> useRakNetChannelFactory(Bootstrap instance, Class<? extends Channel> channelTypeClass, @Local(argsOnly = true) ClientConnection clientConnection) {
|
||||
if (VersionEnum.bedrockLatest.equals(((IClientConnection) clientConnection).viaFabricPlus$getTargetVersion())) {
|
||||
return instance.channelFactory(channelTypeClass == EpollSocketChannel.class ?
|
||||
RakChannelFactory.client(EpollDatagramChannel.class) :
|
||||
RakChannelFactory.client(NioDatagramChannel.class)
|
||||
);
|
||||
}
|
||||
|
||||
return instance.channel(channelTypeClass);
|
||||
}
|
||||
|
||||
@Redirect(method = "connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/network/ClientConnection;)Lio/netty/channel/ChannelFuture;", at = @At(value = "INVOKE", target = "Lio/netty/bootstrap/Bootstrap;connect(Ljava/net/InetAddress;I)Lio/netty/channel/ChannelFuture;", remap = false))
|
||||
private static ChannelFuture useRakNetPingHandlers(Bootstrap instance, InetAddress inetHost, int inetPort, @Local(argsOnly = true) ClientConnection clientConnection, @Local(argsOnly = true) boolean isConnecting) {
|
||||
if (BedrockProtocolVersion.bedrockLatest.equals(((IClientConnection) clientConnection).viaFabricPlus$getTargetVersion()) && !isConnecting) {
|
||||
if (VersionEnum.bedrockLatest.equals(((IClientConnection) clientConnection).viaFabricPlus$getTargetVersion()) && !isConnecting) {
|
||||
// Bedrock edition / RakNet has different handlers for pinging a server
|
||||
return instance.register().syncUninterruptibly().channel().bind(new InetSocketAddress(0)).addListeners(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE, (ChannelFutureListener) f -> {
|
||||
if (f.isSuccess()) {
|
||||
f.channel().pipeline().replace(
|
||||
VLPipeline.VIABEDROCK_FRAME_ENCAPSULATION_HANDLER_NAME,
|
||||
ViaFabricPlusVLLegacyPipeline.VIABEDROCK_PING_ENCAPSULATION_HANDLER_NAME,
|
||||
new PingEncapsulationCodec(new InetSocketAddress(inetHost, inetPort))
|
||||
);
|
||||
f.channel().pipeline().remove(VLPipeline.VIABEDROCK_PACKET_ENCAPSULATION_HANDLER_NAME);
|
||||
f.channel().pipeline().remove(HandlerNames.SPLITTER);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return instance.connect(inetHost, inetPort);
|
||||
return instance.register().syncUninterruptibly().channel().bind(new InetSocketAddress(0)).
|
||||
addListeners(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE, (ChannelFutureListener) f -> {
|
||||
if (f.isSuccess()) {
|
||||
f.channel().pipeline().replace(
|
||||
VLPipeline.VIABEDROCK_FRAME_ENCAPSULATION_HANDLER_NAME,
|
||||
ViaFabricPlusVLLegacyPipeline.VIABEDROCK_PING_ENCAPSULATION_HANDLER_NAME,
|
||||
new PingEncapsulationCodec(new InetSocketAddress(inetHost, inetPort))
|
||||
);
|
||||
f.channel().pipeline().remove(VLPipeline.VIABEDROCK_PACKET_ENCAPSULATION_HANDLER_NAME);
|
||||
f.channel().pipeline().remove("splitter");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return instance.connect(inetHost, inetPort);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -187,7 +193,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
|
||||
@ -201,12 +207,12 @@ public abstract class MixinClientConnection extends SimpleChannelInboundHandler<
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolVersion viaFabricPlus$getTargetVersion() {
|
||||
public VersionEnum viaFabricPlus$getTargetVersion() {
|
||||
return this.viaFabricPlus$serverVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void viaFabricPlus$setTargetVersion(final ProtocolVersion serverVersion) {
|
||||
public void viaFabricPlus$setTargetVersion(final VersionEnum serverVersion) {
|
||||
this.viaFabricPlus$serverVersion = serverVersion;
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.injection.mixin.base.connect;
|
||||
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import io.netty.channel.Channel;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
@ -38,7 +38,7 @@ public abstract class MixinClientConnection_1 {
|
||||
|
||||
@Inject(method = "initChannel", at = @At("RETURN"))
|
||||
private void injectViaIntoPipeline(Channel channel, CallbackInfo ci) {
|
||||
ProtocolTranslator.injectViaPipeline(this.field_11663, channel);
|
||||
ProtocolHack.injectViaPipeline(this.field_11663, channel);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ import de.florianmichael.viafabricplus.injection.access.IClientConnection;
|
||||
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 net.raphimc.vialoader.util.VersionEnum;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@ -43,7 +43,7 @@ public abstract class MixinClientLoginNetworkHandler {
|
||||
@Inject(method = "joinServerSession", at = @At("HEAD"), cancellable = true)
|
||||
public void onlyVerifySessionInOnlineMode(String serverId, CallbackInfoReturnable<Text> cir) {
|
||||
final IClientConnection mixinClientConnection = (IClientConnection) connection;
|
||||
if (mixinClientConnection.viaFabricPlus$getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
|
||||
if (mixinClientConnection.viaFabricPlus$getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_6_4)) {
|
||||
// We are in the 1.7 -> 1.6 protocol, so we need to skip the joinServer call
|
||||
// if the server is in offline mode, due the packet changes <-> networking changes
|
||||
// Minecraft's networking code is bad for us.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -19,7 +19,6 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.injection.mixin.base.integration;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import de.florianmichael.viafabricplus.injection.access.IServerInfo;
|
||||
import de.florianmichael.viafabricplus.screen.base.PerServerVersionScreen;
|
||||
import de.florianmichael.viafabricplus.settings.impl.GeneralSettings;
|
||||
@ -29,6 +28,7 @@ import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.client.network.ServerInfo;
|
||||
import net.minecraft.text.Text;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@ -62,12 +62,7 @@ public abstract class MixinAddServerScreen extends Screen {
|
||||
|
||||
@Inject(method = "init", at = @At("RETURN"))
|
||||
private void addVersionSetterButton(CallbackInfo ci) {
|
||||
final int buttonPosition = GeneralSettings.global().addServerScreenButtonOrientation.getIndex();
|
||||
if (buttonPosition == 0) { // Off
|
||||
return;
|
||||
}
|
||||
|
||||
final ProtocolVersion forcedVersion = ((IServerInfo) server).viaFabricPlus$forcedVersion();
|
||||
final VersionEnum forcedVersion = ((IServerInfo) server).viaFabricPlus$forcedVersion();
|
||||
|
||||
// Restore input if the user cancels the version selection screen (or if the user is editing an existing server)
|
||||
if (viaFabricPlus$nameField != null && viaFabricPlus$addressField != null) {
|
||||
@ -78,7 +73,8 @@ 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 -> {
|
||||
// Create the 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();
|
||||
@ -86,8 +82,11 @@ public abstract class MixinAddServerScreen extends Screen {
|
||||
client.setScreen(new PerServerVersionScreen(this, version -> ((IServerInfo) server).viaFabricPlus$forceVersion(version)));
|
||||
}).size(98, 20);
|
||||
|
||||
// Set the button's position according to the configured orientation and add the button to the screen
|
||||
this.addDrawableChild(GeneralSettings.withOrientation(buttonBuilder, buttonPosition, width, height).build());
|
||||
// Set the button's position according to the configured orientation
|
||||
buttonBuilder = GeneralSettings.withOrientation(buttonBuilder, GeneralSettings.global().addServerScreenButtonOrientation.getIndex(), width, height);
|
||||
|
||||
// Add the button to the screen
|
||||
this.addDrawableChild(buttonBuilder.build());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -21,12 +21,12 @@ package de.florianmichael.viafabricplus.injection.mixin.base.integration;
|
||||
|
||||
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.ViaFabricPlus;
|
||||
import de.florianmichael.viafabricplus.injection.access.IServerInfo;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.impl.provider.vialegacy.ViaFabricPlusClassicMPPassProvider;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.util.ProtocolVersionDetector;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import de.florianmichael.viafabricplus.protocolhack.impl.provider.vialegacy.ViaFabricPlusClassicMPPassProvider;
|
||||
import de.florianmichael.viafabricplus.protocolhack.util.ProtocolVersionDetector;
|
||||
import de.florianmichael.viafabricplus.protocolhack.util.VersionEnumExtension;
|
||||
import de.florianmichael.viafabricplus.settings.impl.AuthenticationSettings;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import net.minecraft.client.gui.screen.multiplayer.ConnectScreen;
|
||||
@ -34,6 +34,7 @@ import net.minecraft.client.network.ServerInfo;
|
||||
import net.minecraft.client.session.Session;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.minecraft.text.Text;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@ -61,21 +62,20 @@ public abstract class MixinConnectScreen_1 {
|
||||
private ChannelFuture setServerInfoAndHandleDisconnect(InetSocketAddress address, boolean useEpoll, ClientConnection connection, Operation<ChannelFuture> original) {
|
||||
final IServerInfo mixinServerInfo = (IServerInfo) this.field_40415;
|
||||
|
||||
ProtocolVersion targetVersion = ProtocolTranslator.getTargetVersion();
|
||||
VersionEnum targetVersion = ProtocolHack.getTargetVersion();
|
||||
if (mixinServerInfo.viaFabricPlus$forcedVersion() != null && !mixinServerInfo.viaFabricPlus$passedDirectConnectScreen()) {
|
||||
targetVersion = mixinServerInfo.viaFabricPlus$forcedVersion();
|
||||
mixinServerInfo.viaFabricPlus$passDirectConnectScreen(false); // reset state
|
||||
}
|
||||
if (targetVersion == ProtocolTranslator.AUTO_DETECT_PROTOCOL) {
|
||||
if (targetVersion == VersionEnumExtension.AUTO_DETECT) {
|
||||
this.field_2416.setStatus(Text.translatable("base.viafabricplus.detecting_server_version"));
|
||||
targetVersion = ProtocolVersionDetector.get(address, ProtocolTranslator.NATIVE_VERSION);
|
||||
targetVersion = ProtocolVersionDetector.get(address, ProtocolHack.NATIVE_VERSION);
|
||||
}
|
||||
ProtocolTranslator.setTargetVersion(targetVersion, true);
|
||||
ProtocolHack.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());
|
||||
future.channel().closeFuture().addListener(channel -> ProtocolHack.resetPreviousVersion());
|
||||
|
||||
return future;
|
||||
}
|
||||
@ -84,8 +84,11 @@ public abstract class MixinConnectScreen_1 {
|
||||
private String useClassiCubeUsername(Session instance) {
|
||||
if (this.viaFabricPlus$useClassiCubeAccount) {
|
||||
final var account = ViaFabricPlus.global().getSaveManager().getAccountsSave().getClassicubeAccount();
|
||||
if (account != null) return account.username();
|
||||
if (account != null) {
|
||||
return account.username();
|
||||
}
|
||||
}
|
||||
|
||||
return instance.getUsername();
|
||||
}
|
||||
|
||||
|
@ -21,23 +21,23 @@ 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 com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
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;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import de.florianmichael.viafabricplus.settings.impl.GeneralSettings;
|
||||
import de.florianmichael.viafabricplus.util.ChatUtil;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.hud.DebugHud;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.raphimc.viabedrock.protocol.data.enums.bedrock.ServerAuthMovementMode;
|
||||
import net.raphimc.viabedrock.protocol.data.enums.bedrock.ServerMovementModes;
|
||||
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;
|
||||
@ -54,14 +54,14 @@ public abstract class MixinDebugHud {
|
||||
|
||||
@Inject(method = "getLeftText", at = @At("RETURN"))
|
||||
public void addViaFabricPlusInformation(CallbackInfoReturnable<List<String>> cir) {
|
||||
if (!GeneralSettings.global().showExtraInformationInDebugHud.getValue()) { // Only show if enabled
|
||||
if (!GeneralSettings.global().showExtraInformationInDebugHud.getValue()) {
|
||||
return;
|
||||
}
|
||||
if (MinecraftClient.getInstance().isInSingleplayer() && MinecraftClient.getInstance().player != null) { // Don't show in singleplayer
|
||||
if (MinecraftClient.getInstance().isInSingleplayer() && MinecraftClient.getInstance().player != null) {
|
||||
return;
|
||||
}
|
||||
final UserConnection userConnection = ProtocolTranslator.getPlayNetworkUserConnection();
|
||||
if (userConnection == null) { // Only show if ViaVersion is active
|
||||
final UserConnection userConnection = ProtocolHack.getPlayNetworkUserConnection();
|
||||
if (userConnection == null) { // Via is not translating this session
|
||||
return;
|
||||
}
|
||||
|
||||
@ -71,33 +71,47 @@ public abstract class MixinDebugHud {
|
||||
// Title
|
||||
information.add(ChatUtil.PREFIX + Formatting.RESET + " " + ViaFabricPlusMixinPlugin.VFP_VERSION);
|
||||
|
||||
// Connection
|
||||
// common
|
||||
final ProtocolInfo info = userConnection.getProtocolInfo();
|
||||
information.add("P: " + info.getPipeline().pipes().size() + " C: " + info.protocolVersion() + " S: " + info.serverProtocolVersion());
|
||||
information.add(
|
||||
"P: " + info.getPipeline().pipes().size() +
|
||||
" C: " + ProtocolVersion.getProtocol(info.getProtocolVersion()) +
|
||||
" S: " + ProtocolVersion.getProtocol(info.getServerProtocolVersion())
|
||||
);
|
||||
|
||||
// 1.7.10
|
||||
// r1_7_10
|
||||
final EntityTracker entityTracker1_7_10 = userConnection.get(EntityTracker.class);
|
||||
if (entityTracker1_7_10 != null) {
|
||||
information.add("1.7 Entities: " + entityTracker1_7_10.getTrackedEntities().size() + ", Virtual holograms: " + entityTracker1_7_10.getVirtualHolograms().size());
|
||||
information.add(
|
||||
"1.7 Entities: " + entityTracker1_7_10.getTrackedEntities().size() +
|
||||
", Virtual holograms: " + entityTracker1_7_10.getVirtualHolograms().size()
|
||||
);
|
||||
}
|
||||
|
||||
// 1.1
|
||||
// r1_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);
|
||||
}
|
||||
|
||||
// c0.30 cpe
|
||||
// c0.30cpe
|
||||
final ExtensionProtocolMetadataStorage extensionProtocolMetadataStorage = userConnection.get(ExtensionProtocolMetadataStorage.class);
|
||||
if (extensionProtocolMetadataStorage != null) {
|
||||
information.add("CPE extensions: " + extensionProtocolMetadataStorage.getExtensionCount());
|
||||
}
|
||||
|
||||
// Bedrock
|
||||
final BedrockJoinGameTracker joinGameDataTracker = userConnection.get(BedrockJoinGameTracker.class);
|
||||
// bedrock
|
||||
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());
|
||||
final int movementMode = userConnection.get(GameSessionStorage.class).getMovementMode();
|
||||
String movement = "Server with rewind";
|
||||
if (movementMode == ServerMovementModes.CLIENT) {
|
||||
movement = "Client";
|
||||
} else if (movementMode == ServerMovementModes.SERVER) {
|
||||
movement = "Server";
|
||||
}
|
||||
|
||||
information.add("Bedrock Level: " + joinGameDataTracker.getLevelId() + ", Enchantment Seed: " + joinGameDataTracker.getEnchantmentSeed() + ", Movement: " + movement);
|
||||
}
|
||||
if (joinGameDataTracker != null) {
|
||||
information.add("World Seed: " + joinGameDataTracker.getSeed());
|
||||
|
@ -20,14 +20,14 @@
|
||||
package de.florianmichael.viafabricplus.injection.mixin.base.integration;
|
||||
|
||||
import com.viaversion.viaversion.api.connection.UserConnection;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import de.florianmichael.viafabricplus.settings.impl.GeneralSettings;
|
||||
import de.florianmichael.viafabricplus.util.ChatUtil;
|
||||
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;
|
||||
@ -44,7 +44,7 @@ public abstract class MixinDownloadingTerrainScreen extends Screen {
|
||||
private void renderClassicProgress(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
|
||||
if (GeneralSettings.global().showClassicLoadingProgressInConnectScreen.getValue()) {
|
||||
// Check if ViaVersion is translating
|
||||
final UserConnection connection = ProtocolTranslator.getPlayNetworkUserConnection();
|
||||
final UserConnection connection = ProtocolHack.getPlayNetworkUserConnection();
|
||||
if (connection == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -19,15 +19,10 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.injection.mixin.base.integration;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import de.florianmichael.viafabricplus.event.PostGameLoadCallback;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.RunArgs;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import net.minecraft.resource.ResourcePackManager;
|
||||
import net.minecraft.server.SaveLoader;
|
||||
import net.minecraft.world.level.storage.LevelStorage;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
@ -41,10 +36,11 @@ public abstract class MixinMinecraftClient {
|
||||
PostGameLoadCallback.EVENT.invoker().postGameLoad();
|
||||
}
|
||||
|
||||
@Inject(method = "startIntegratedServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;connect(Ljava/lang/String;ILnet/minecraft/network/listener/ClientLoginPacketListener;)V", shift = At.Shift.BEFORE))
|
||||
private void disableProtocolTranslator(LevelStorage.Session session, ResourcePackManager dataPackManager, SaveLoader saveLoader, boolean newWorld, CallbackInfo ci, @Local ClientConnection clientConnection) {
|
||||
ProtocolTranslator.setTargetVersion(ProtocolTranslator.NATIVE_VERSION, true);
|
||||
ProtocolTranslator.injectPreviousVersionReset(clientConnection.channel);
|
||||
@Inject(method = "startIntegratedServer", at = @At("HEAD"))
|
||||
private void disableProtocolHack(CallbackInfo ci) {
|
||||
// Set the target version to the native version when starting a singleplayer world
|
||||
// This will automatically reload all the mappings and reset the target version to the forced version
|
||||
ProtocolHack.setTargetVersion(ProtocolHack.NATIVE_VERSION);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,20 +19,11 @@
|
||||
|
||||
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;
|
||||
import de.florianmichael.viafabricplus.screen.base.ProtocolSelectionScreen;
|
||||
import de.florianmichael.viafabricplus.settings.impl.GeneralSettings;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.network.ServerAddress;
|
||||
import net.minecraft.client.network.ServerInfo;
|
||||
import net.minecraft.text.Text;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@ -48,27 +39,14 @@ public abstract class MixinMultiplayerScreen extends Screen {
|
||||
|
||||
@Inject(method = "init", at = @At("RETURN"))
|
||||
private void addProtocolSelectionButton(CallbackInfo ci) {
|
||||
final int buttonPosition = GeneralSettings.global().multiplayerScreenButtonOrientation.getIndex();
|
||||
if (buttonPosition == 0) { // Off
|
||||
return;
|
||||
}
|
||||
ButtonWidget.Builder builder = ButtonWidget.builder(Text.of("ViaFabricPlus"), button -> ProtocolSelectionScreen.INSTANCE.open(this)).size(98, 20);
|
||||
// Create the button
|
||||
var 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());
|
||||
}
|
||||
// Set the button's position according to the configured orientation
|
||||
builder = GeneralSettings.withOrientation(builder, GeneralSettings.global().multiplayerScreenButtonOrientation.getIndex(), width, height);
|
||||
|
||||
@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();
|
||||
} else {
|
||||
version = mixinServerInfo.viaFabricPlus$forcedVersion();
|
||||
}
|
||||
return original.call(ClientsideFixes.replaceDefaultPort(address, version));
|
||||
// Add the button to the screen
|
||||
this.addDrawableChild(builder.build());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.injection.mixin.base.integration;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import de.florianmichael.viafabricplus.injection.access.IClientConnection;
|
||||
import de.florianmichael.viafabricplus.injection.access.IServerInfo;
|
||||
import net.minecraft.SharedConstants;
|
||||
@ -27,6 +26,9 @@ 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 net.raphimc.vialoader.util.VersionEnum;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@ -55,11 +57,31 @@ public abstract class MixinMultiplayerServerListPinger_1 implements ClientQueryP
|
||||
}
|
||||
|
||||
@Inject(method = "onResponse", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;send(Lnet/minecraft/network/packet/Packet;)V", shift = At.Shift.AFTER))
|
||||
private void fixVersionComparison(CallbackInfo ci) {
|
||||
final ProtocolVersion version = ((IClientConnection) this.field_3774).viaFabricPlus$getTargetVersion();
|
||||
private void setProtocolVersion(CallbackInfo ci) {
|
||||
final VersionEnum version = ((IClientConnection) this.field_3774).viaFabricPlus$getTargetVersion();
|
||||
|
||||
// ViaVersion is not translating the current connection, so we don't need to do anything
|
||||
if (version == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean isCompatible;
|
||||
if (version.isOlderThanOrEqualTo(VersionEnum.r1_6_4)) {
|
||||
// Because of ViaVersion not supporting legacy minecraft versions where protocol ids are overlapping, ViaLegacy
|
||||
// has its own protocol id offset, where realVersion = -(ViaLegacyVersion >> 2). Normally ViaVersion sends the client
|
||||
// version to the client so its detection doesn't break when checking for serverVersion == clientVersion, but since
|
||||
// ViaLegacy doesn't do that, we have to do it ourselves
|
||||
isCompatible = LegacyProtocolVersion.getRealProtocolVersion(version.getVersion()) == this.field_3776.protocolVersion;
|
||||
} else if (version.equals(VersionEnum.bedrockLatest)) {
|
||||
// Bedrock edition doesn't have a protocol id like the Java edition, ViaBedrock also has its own protocol id offset
|
||||
// Which we need to remove to get the real protocol id
|
||||
isCompatible = version.getVersion() - BedrockProtocolVersion.PROTOCOL_ID_OVERLAP_PREVENTION_OFFSET == this.field_3776.protocolVersion;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the server is compatible with the client, we set the protocol version to the client version
|
||||
if (version != null && version.getVersion() == this.field_3776.protocolVersion) {
|
||||
if (isCompatible) {
|
||||
this.field_3776.protocolVersion = SharedConstants.getProtocolVersion();
|
||||
}
|
||||
}
|
||||
|
@ -19,33 +19,22 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.injection.mixin.base.integration;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import de.florianmichael.viafabricplus.injection.access.IServerInfo;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import de.florianmichael.viafabricplus.settings.impl.GeneralSettings;
|
||||
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
|
||||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerServerListWidget;
|
||||
import net.minecraft.client.gui.screen.world.WorldIcon;
|
||||
import net.minecraft.client.network.ServerInfo;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.text.OrderedText;
|
||||
import net.minecraft.text.StringVisitable;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.spongepowered.asm.mixin.*;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Mixin(MultiplayerServerListWidget.ServerEntry.class)
|
||||
public abstract class MixinMultiplayerServerListWidget_ServerEntry {
|
||||
@ -54,86 +43,19 @@ public abstract class MixinMultiplayerServerListWidget_ServerEntry {
|
||||
@Final
|
||||
private ServerInfo server;
|
||||
|
||||
@Mutable
|
||||
@Shadow
|
||||
@Final
|
||||
private WorldIcon icon;
|
||||
|
||||
@Unique
|
||||
private boolean viaFabricPlus$disableServerPinging = false;
|
||||
|
||||
@WrapWithCondition(method = "render", at = @At(value = "INVOKE", target = "Ljava/util/concurrent/ThreadPoolExecutor;submit(Ljava/lang/Runnable;)Ljava/util/concurrent/Future;"))
|
||||
private boolean disableServerPinging(ThreadPoolExecutor instance, Runnable runnable) {
|
||||
ProtocolVersion version = ((IServerInfo) server).viaFabricPlus$forcedVersion();
|
||||
if (version == null) version = ProtocolTranslator.getTargetVersion();
|
||||
|
||||
viaFabricPlus$disableServerPinging = VisualSettings.global().disableServerPinging.isEnabled(version);
|
||||
if (viaFabricPlus$disableServerPinging) {
|
||||
this.server.version = Text.of(version.getName()); // Show target version
|
||||
}
|
||||
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() {
|
||||
if (viaFabricPlus$disableServerPinging) {
|
||||
return this.server.getStatus(); // server version will always be shown (as we don't have a player count anyway)
|
||||
} else {
|
||||
return ServerInfo.Status.INCOMPATIBLE;
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/font/TextRenderer;wrapLines(Lnet/minecraft/text/StringVisitable;I)Ljava/util/List;"))
|
||||
private List<OrderedText> disableServerPinging(TextRenderer instance, StringVisitable text, int width) {
|
||||
if (viaFabricPlus$disableServerPinging) { // server label will just show the server address
|
||||
return instance.wrapLines(Text.of(server.address), width);
|
||||
} else {
|
||||
return instance.wrapLines(text, width);
|
||||
}
|
||||
}
|
||||
|
||||
@ModifyArg(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawText(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/text/Text;IIIZ)I"), index = 2)
|
||||
private int disableServerPinging(int x) {
|
||||
if (viaFabricPlus$disableServerPinging) { // Move server label to the right (as we remove the ping bar)
|
||||
x += 15 /* ping bar width */ - 3 /* magical offset */;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
@WrapWithCondition(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Ljava/util/function/Function;Lnet/minecraft/util/Identifier;IIII)V", ordinal = 0))
|
||||
private boolean disableServerPinging(DrawContext instance, Function<Identifier, RenderLayer> renderLayers, Identifier sprite, int x, int y, int width, int height) {
|
||||
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"))
|
||||
private boolean disableServerPinging(MultiplayerScreen instance, List<Text> tooltip) {
|
||||
return !viaFabricPlus$disableServerPinging; // Remove player list tooltip
|
||||
}
|
||||
|
||||
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/world/WorldIcon;getTextureId()Lnet/minecraft/util/Identifier;"))
|
||||
private Identifier disableServerPinging(WorldIcon instance) {
|
||||
if (viaFabricPlus$disableServerPinging) { // Remove server icon
|
||||
return WorldIcon.UNKNOWN_SERVER_ID;
|
||||
} else {
|
||||
return this.icon.getTextureId();
|
||||
}
|
||||
}
|
||||
|
||||
@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
|
||||
return;
|
||||
}
|
||||
final List<Text> tooltips = new ArrayList<>();
|
||||
tooltips.add(text);
|
||||
@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) {
|
||||
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 + ")"));
|
||||
final VersionEnum versionEnum = ((IServerInfo) server).viaFabricPlus$translatingVersion();
|
||||
|
||||
if (versionEnum != null) {
|
||||
tooltipCopy.add(Text.translatable("base.viafabricplus.via_translates_to", versionEnum.getName() + " (" + versionEnum.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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,24 +19,23 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.injection.mixin.base.perserverversion;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import de.florianmichael.viafabricplus.injection.access.IServerInfo;
|
||||
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;
|
||||
import net.minecraft.client.network.ServerInfo;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(MultiplayerScreen.class)
|
||||
public abstract class MixinMultiplayerScreen {
|
||||
|
||||
@Shadow protected abstract void connect(ServerInfo entry);
|
||||
|
||||
@WrapOperation(method = "directConnect", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;connect(Lnet/minecraft/client/network/ServerInfo;)V"))
|
||||
private void storeDirectConnectionPhase(MultiplayerScreen instance, ServerInfo entry, Operation<Void> original) {
|
||||
((IServerInfo) entry).viaFabricPlus$passDirectConnectScreen(true);
|
||||
original.call(instance, entry);
|
||||
@Redirect(method = "directConnect", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/multiplayer/MultiplayerScreen;connect(Lnet/minecraft/client/network/ServerInfo;)V"))
|
||||
private void storeDirectConnectionPhase(MultiplayerScreen instance, ServerInfo entry) {
|
||||
((IServerInfo) entry).viaFabricPlus$passDirectConnectScreen();
|
||||
connect(entry);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,49 +19,40 @@
|
||||
|
||||
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 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 net.raphimc.vialoader.util.VersionEnum;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import 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) {
|
||||
// Replace port when pinging the server and the forced version is set
|
||||
return original.call(ClientsideFixes.replaceDefaultPort(address, ((IServerInfo) entry).viaFabricPlus$forcedVersion()));
|
||||
}
|
||||
@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 ServerInfo serverInfo) {
|
||||
final VersionEnum forcedVersion = ((IServerInfo) serverInfo).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) {
|
||||
final IServerInfo mixinServerInfo = (IServerInfo) serverInfo;
|
||||
|
||||
if (mixinServerInfo.viaFabricPlus$forcedVersion() != null && !mixinServerInfo.viaFabricPlus$passedDirectConnectScreen()) {
|
||||
if (forcedVersion != null && !((IServerInfo) serverInfo).viaFabricPlus$passedDirectConnectScreen()) {
|
||||
// We use the PerformanceLog field to store the forced version since it's always null when pinging a server
|
||||
// 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());
|
||||
mixinServerInfo.viaFabricPlus$passDirectConnectScreen(false);
|
||||
((IPerformanceLog) packetSizeLog).viaFabricPlus$setForcedVersion(forcedVersion);
|
||||
}
|
||||
|
||||
return original.call(address, useEpoll, packetSizeLog);
|
||||
return ClientConnection.connect(address, useEpoll, packetSizeLog);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,25 +19,25 @@
|
||||
|
||||
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 net.raphimc.vialoader.util.VersionEnum;
|
||||
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;
|
||||
private VersionEnum viaFabricPlus$forcedVersion;
|
||||
|
||||
@Override
|
||||
public ProtocolVersion viaFabricPlus$getForcedVersion() {
|
||||
public VersionEnum viaFabricPlus$getForcedVersion() {
|
||||
return this.viaFabricPlus$forcedVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void viaFabricPlus$setForcedVersion(ProtocolVersion version) {
|
||||
public void viaFabricPlus$setForcedVersion(VersionEnum version) {
|
||||
this.viaFabricPlus$forcedVersion = version;
|
||||
}
|
||||
|
@ -19,12 +19,10 @@
|
||||
|
||||
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 net.raphimc.vialoader.util.VersionEnum;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
@ -32,6 +30,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
@Mixin(ServerInfo.class)
|
||||
public abstract class MixinServerInfo implements IServerInfo {
|
||||
@ -40,26 +39,30 @@ public abstract class MixinServerInfo implements IServerInfo {
|
||||
public String name;
|
||||
|
||||
@Unique
|
||||
private ProtocolVersion viaFabricPlus$forcedVersion = null;
|
||||
private VersionEnum viaFabricPlus$forcedVersion = null;
|
||||
|
||||
@Unique
|
||||
private boolean viaFabricPlus$passedDirectConnectScreen;
|
||||
|
||||
@Unique
|
||||
private ProtocolVersion viaFabricPlus$translatingVersion;
|
||||
private VersionEnum viaFabricPlus$translatingVersion;
|
||||
|
||||
@Inject(method = "toNbt", at = @At("TAIL"))
|
||||
private void saveForcedVersion(CallbackInfoReturnable<NbtCompound> cir, @Local NbtCompound nbtCompound) {
|
||||
if (viaFabricPlus$forcedVersion != null) {
|
||||
nbtCompound.putString("viafabricplus_forcedversion", viaFabricPlus$forcedVersion.getName());
|
||||
@Inject(method = "toNbt", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
private void saveForcedVersion(CallbackInfoReturnable<NbtCompound> cir, NbtCompound nbtCompound) {
|
||||
if (viaFabricPlus$forcedVersion == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
nbtCompound.putInt("viafabricplus_forcedversion", viaFabricPlus$forcedVersion.getOriginalVersion());
|
||||
}
|
||||
|
||||
@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"));
|
||||
if (version != null) {
|
||||
final VersionEnum version = VersionEnum.fromProtocolId(root.getInt("viafabricplus_forcedversion"));
|
||||
if (VersionEnum.UNKNOWN.equals(version)) {
|
||||
((IServerInfo) serverInfo).viaFabricPlus$forceVersion(null);
|
||||
} else {
|
||||
((IServerInfo) serverInfo).viaFabricPlus$forceVersion(version);
|
||||
}
|
||||
}
|
||||
@ -71,32 +74,35 @@ public abstract class MixinServerInfo implements IServerInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolVersion viaFabricPlus$forcedVersion() {
|
||||
public VersionEnum viaFabricPlus$forcedVersion() {
|
||||
return viaFabricPlus$forcedVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void viaFabricPlus$forceVersion(ProtocolVersion version) {
|
||||
public void viaFabricPlus$forceVersion(VersionEnum version) {
|
||||
viaFabricPlus$forcedVersion = version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean viaFabricPlus$passedDirectConnectScreen() {
|
||||
return viaFabricPlus$passedDirectConnectScreen;
|
||||
final boolean previous = viaFabricPlus$passedDirectConnectScreen;
|
||||
viaFabricPlus$passedDirectConnectScreen = false;
|
||||
|
||||
return previous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void viaFabricPlus$passDirectConnectScreen(boolean state) {
|
||||
viaFabricPlus$passedDirectConnectScreen = state;
|
||||
public void viaFabricPlus$passDirectConnectScreen() {
|
||||
viaFabricPlus$passedDirectConnectScreen = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolVersion viaFabricPlus$translatingVersion() {
|
||||
public VersionEnum viaFabricPlus$translatingVersion() {
|
||||
return viaFabricPlus$translatingVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void viaFabricPlus$setTranslatingVersion(ProtocolVersion version) {
|
||||
public void viaFabricPlus$setTranslatingVersion(VersionEnum version) {
|
||||
viaFabricPlus$translatingVersion = version;
|
||||
}
|
||||
|
||||
|
@ -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,18 +37,22 @@ 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);
|
||||
if (this.viaFabricPlus$forbiddenCharactersUnlocked) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -19,8 +19,8 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.injection.mixin.compat.ipnext;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Pseudo;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@ -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 {
|
||||
@ -44,14 +43,14 @@ public abstract class MixinAutoRefillHandler_ItemSlotMonitor {
|
||||
|
||||
@Inject(method = { "checkHandle", "checkShouldHandle" }, at = @At("HEAD"), cancellable = true)
|
||||
public void dontHandleOffhandSlot(CallbackInfo ci) {
|
||||
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
|
||||
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
|
||||
if (currentSlotId == 45) ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "updateCurrent", at = @At(value = "FIELD", target = "Lorg/anti_ad/mc/ipnext/event/AutoRefillHandler$ItemSlotMonitor;currentSlotId:I", shift = At.Shift.AFTER), cancellable = true)
|
||||
public void dontUpdateCurrentOffhandSlot(CallbackInfo ci) {
|
||||
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
|
||||
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_8)) {
|
||||
if (currentSlotId == 45) ci.cancel();
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
@ -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,14 +26,14 @@ 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)
|
||||
public abstract class MixinDefaultJwtParserBuilder {
|
||||
|
||||
@Redirect(method = "build()Lio/jsonwebtoken/JwtParser;", at = @At(value = "INVOKE", target = "Lio/jsonwebtoken/impl/lang/Services;get(Ljava/lang/Class;)Ljava/lang/Object;"))
|
||||
public Object removeServicesSupport(Class<?> spi) {
|
||||
@Redirect(method = "build()Lio/jsonwebtoken/JwtParser;", at = @At(value = "INVOKE", target = "Lio/jsonwebtoken/impl/lang/Services;loadFirst(Ljava/lang/Class;)Ljava/lang/Object;"))
|
||||
public Object removeServicesSupport(Class<Object> result) {
|
||||
return new GsonDeserializer<>();
|
||||
}
|
||||
|
@ -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.compat.lithium;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import net.minecraft.entity.Entity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
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/11892b8c0f0f14e81c3384510b0b2ac7293ca237/common/src/main/java/net/caffeinemc/mods/lithium/mixin/entity/collisions/movement/EntityMixin.java#L84
|
||||
@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)
|
||||
private static double alwaysSortYXZ(double a) {
|
||||
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_13_2)) {
|
||||
return Double.MAX_VALUE;
|
||||
} else {
|
||||
return Math.abs(a);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -23,7 +23,7 @@ import com.mojang.authlib.minecraft.client.MinecraftClient;
|
||||
import com.mojang.authlib.yggdrasil.YggdrasilUserApiService;
|
||||
import com.mojang.authlib.yggdrasil.response.KeyPairResponse;
|
||||
import de.florianmichael.viafabricplus.ViaFabricPlus;
|
||||
import de.florianmichael.viafabricplus.fixes.versioned.KeyPairResponse1_19_0;
|
||||
import de.florianmichael.viafabricplus.fixes.replacement.KeyPairResponse1_19_0;
|
||||
import de.florianmichael.viafabricplus.injection.access.ILegacyKeySignatureStorage;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
@ -19,13 +19,12 @@
|
||||
|
||||
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
|
||||
|
||||
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
|
||||
import de.florianmichael.viafabricplus.protocolhack.ProtocolHack;
|
||||
import net.minecraft.client.network.Address;
|
||||
import net.minecraft.client.network.AddressResolver;
|
||||
import net.minecraft.client.network.AllowedAddressResolver;
|
||||
import net.minecraft.client.network.ServerAddress;
|
||||
import net.raphimc.viabedrock.api.BedrockProtocolVersion;
|
||||
import net.raphimc.vialoader.util.VersionEnum;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@ -44,7 +43,7 @@ public abstract class MixinAllowedAddressResolver {
|
||||
|
||||
@Inject(method = "resolve", at = @At("HEAD"), cancellable = true)
|
||||
private void oldResolveBehaviour(ServerAddress address, CallbackInfoReturnable<Optional<Address>> cir) {
|
||||
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_16_4) || ProtocolTranslator.getTargetVersion().equals(BedrockProtocolVersion.bedrockLatest)) {
|
||||
if (ProtocolHack.getTargetVersion().isOlderThanOrEqualTo(VersionEnum.r1_16_4tor1_16_5) || ProtocolHack.getTargetVersion().equals(VersionEnum.bedrockLatest)) {
|
||||
cir.setReturnValue(this.addressResolver.resolve(address));
|
||||
}
|
||||
}
|
||||
|