Compare commits

...

156 Commits
v3.1.1 ... main

Author SHA1 Message Date
FlorianMichael
09be940b25
Add setting for legacy tab completions in <= 1.12.2 2024-06-25 18:52:41 +02:00
FlorianMichael
196dff92f8
Fixup injection conflict with polymer mod
Closes https://github.com/ViaVersion/ViaFabricPlus/issues/461
2024-06-24 02:02:43 +02:00
RK_01
395ad80d91
Add 3D Shareware 8-Bit sound (#459) 2024-06-23 14:18:15 +02:00
FlorianMichael
1225016fa9
Bump version to 3.4.2-SNAPSHOT 2024-06-22 16:36:32 +02:00
FlorianMichael
2c29f84dc7
Release 3.4.1 2024-06-22 16:25:06 +02:00
FlorianMichael
8863e9eaad
Fix remap = false in MixinRegistrySyncManager 2024-06-22 16:22:55 +02:00
FlorianMichael
0d06dc7fec
Back to Via* release versions 2024-06-22 16:18:53 +02:00
FlorianMichael
4f1f044837
Always reference newest version in injection names 2024-06-22 15:05:44 +02:00
RK_01
b966022f74
Readd "air stepping" mechanic in <= 1.20.6 (#458)
Fixes #454
2024-06-22 15:02:22 +02:00
FlorianMichael
ab9fd7edd6
Add setting to ignore Fabric registry sync errors
See https://github.com/ViaVersion/ViaFabric/pull/341
Closes https://github.com/ViaVersion/ViaFabricPlus/issues/455
2024-06-22 00:13:47 +02:00
FlorianMichael
c457a6f4ef
Add required maven repositories to DEVELOPER_API.md, cleanup build.gradle 2024-06-21 13:26:29 +02:00
RK_01
f646b8c965
Handle some enchantments clientside in <= 1.20.5 (#453)
* Handle more enchantments clientside

* Handle aqua affinity clientside
2024-06-20 20:05:36 +02:00
RaphiMC
ce94e07c27
Make mixin methods private 2024-06-20 01:29:09 +02:00
FlorianMichael
9ff009237d
Re-add old WON_GAME state handling in <= 1.20.5 2024-06-20 01:29:08 +02:00
FlorianMichael
0ed772f477
Don't apply base values from attributes in <= 1.20.5 2024-06-20 01:29:03 +02:00
FlorianMichael
08ed70e4d9
Bump version to 3.4.1-SNAPSHOT 2024-06-19 20:43:20 +02:00
FlorianMichael
45a1633f0a
Release 3.4.0 2024-06-19 20:36:01 +02:00
FlorianMichael
5c3933118b
Update Via* libraries 2024-06-19 20:34:10 +02:00
Blay
60ae10c8e5
Update polish translations (#452) 2024-06-19 19:47:27 +02:00
FlorianMichael
8a69e037ab
Fixup MixinMouseOptionsScreen, update todo list 2024-06-18 15:00:05 +02:00
FlorianMichael
8f01f4e35c
Update VV and VB to snapshots 2024-06-18 14:01:25 +02:00
RaphiMC
3a16c4752f
Fix fabric.mod.json supported version range 2024-06-18 11:48:21 +02:00
bluegreensea
0027e681ee
Update lithium compat 2024-06-17 17:43:06 +02:00
bluegreensea
44b42fe176
Update zh_tw.json 2024-06-17 17:42:28 +02:00
FlorianMichael
085319fbbe
[ci skip] Most 1.21 porting TODOs 2024-06-17 16:49:12 +02:00
RaphiMC
2db9a087a2
Update supported versions in README 2024-06-17 16:45:55 +02:00
RaphiMC
3d48023e20
Initial 1.21 update (#445) 2024-06-16 20:25:08 +02:00
FlorianMichael
72d575797d
Release 3.3.2 2024-06-16 20:19:54 +02:00
FlorianMichael
36362bd1bc
Update Via* libraries 2024-06-16 20:19:20 +02:00
FlorianMichael
5fcf377366
Add copy link button to bedrock login screen
Closes https://github.com/ViaVersion/ViaFabricPlus/issues/444
2024-06-16 16:35:44 +02:00
FlorianMichael
18fd102a68
Update VV API usage 2024-06-15 21:02:44 +02:00
FlorianMichael
0ea07d0e63
Fixup horrible formatting 2024-06-15 16:39:54 +02:00
FlorianMichael
46474fcd22
Remove via subcommands which are not usable on the clientside 2024-06-15 16:10:00 +02:00
RacoonDog
1f8fb02b53
Change particle density in 1.20.3->1.20.5 (#442)
* tweak particle density

* implement changes

* newlined
2024-06-14 18:52:34 +02:00
FlorianMichael
456a5a94b9
Fixup sword blocking in <= 1.8
Closes https://github.com/ViaVersion/ViaFabricPlus/pull/438

Co-authored-by: Error <45919406+OfficialError@users.noreply.github.com>
2024-06-12 04:30:23 +02:00
FlorianMichael
aa27837c56
Fixup jsonwebtoken compat injections
Closes https://github.com/ViaVersion/ViaFabricPlus/issues/437
2024-06-11 22:28:08 +02:00
FlorianMichael
8c34100ee1
Hide Footstep particle from Fabric registry sync
Closes https://github.com/ViaVersion/ViaFabricPlus/issues/430
2024-06-11 20:29:22 +02:00
FlorianMichael
ba925d0a65
Fix wrong farmland version check
Closes https://github.com/ViaVersion/ViaFabricPlus/issues/436
2024-06-11 20:09:25 +02:00
FlorianMichael
6eccfc8849
Fixup classic weather extension 2024-06-11 19:52:12 +02:00
FlorianMichael
0056a53185
Bump version to 3.3.2-SNAPSHOT 2024-06-10 23:33:59 +02:00
FlorianMichael
574657b24b
Release 3.3.1 2024-06-10 23:23:48 +02:00
RaphiMC
1a6a683ebe
Fix transitive JiJ issues 2024-06-10 17:29:08 +02:00
FlorianMichael
3984f6a12d
Replace ClientsideFixes#ATTRIBUTE_FIX_KEY with ItemRewriter API 2024-06-10 10:59:42 +02:00
FlorianMichael
4bb0057ced
Update VV usage 2024-06-10 10:57:55 +02:00
RaphiMC
6fd7e3730e
Add 1.20.3->1.20.5 openWrittenBook fix 2024-06-09 16:53:08 +02:00
FlorianMichael
a199f553af
Cleanup mixins 2024-06-09 16:39:26 +02:00
RaphiMC
088290e352
Clean up TODO list 2024-06-09 16:35:45 +02:00
FlorianMichael
9a9b4a8d88
Bump Fabric API 2024-06-09 12:33:08 +02:00
RaphiMC
8525292b09
Update VV API usage 2024-06-07 15:58:07 +02:00
FlorianMichael
a1f3552944
Disable VV chunk-border-fix option
It doesn't work on some servers and should be fixed properly on game level at some point
2024-06-05 00:43:46 +02:00
FlorianMichael
b230a9e2f7
Default disable VV update checker 2024-06-05 00:29:24 +02:00
FlorianMichael
3366b6766e
Gradle 8.8 2024-06-03 20:30:48 +02:00
FlorianMichael
f538c56b0e
Make mixin abstract, update TODO 2024-06-03 03:20:47 +02:00
FlorianMichael
4b2cf8379d
Go back to normal Via* versions
Kenny and I did all breaking changes for now, and Myles has already fixed the CI issues.
2024-06-02 18:02:14 +02:00
FlorianMichael
25ce9984b6
Add slime/magma_cube dimension change in 1.20.3->.5 2024-05-31 15:16:49 +02:00
FlorianMichael
ef9c9536d6
Update version references 2024-05-30 15:57:42 +02:00
FlorianMichael
3ef13d8426
Add viaversion and viabackwards as provides into fabric.mod.json
Allows mods to commonly check for either viaversion or viabackwards to be loaded
2024-05-30 15:37:25 +02:00
FlorianMichael
22678ba99b
Set handle-invalid-item-count viaversion setting to default true
I don't see any issue with the current implementation, and we will see if I'm right once this release rolls out if it turns out to be wrong later, we can revert this decision easily.
2024-05-30 02:36:47 +02:00
FlorianMichael
996ad2de0d
Update version references 2024-05-30 02:25:42 +02:00
Kichura
5eb9401852
Ensure we use JDK 21, not 17. (#423) 2024-05-28 22:27:43 +02:00
FlorianMichael
49311d479f
Fix footstep particles causes client disconnect
Also carry custom particle id through modern particle mappings
2024-05-28 22:03:19 +02:00
RaphiMC
d0426c82e3
Add new methods to ItemTranslator 2024-05-27 16:27:55 +02:00
RaphiMC
43d5065e1e
Replace Redirect with ModifyExpressionValue
Fixes mod compatibility issue
2024-05-27 14:45:36 +02:00
RaphiMC
1c23746dfc
Update Via* libraries 2024-05-27 14:40:56 +02:00
FlorianMichael
9ba4d1d328
Bump version to 3.3.1-SNAPSHOT 2024-05-26 18:34:33 +02:00
FlorianMichael
64601f91c4
Release 3.3.0 2024-05-26 17:48:07 +02:00
FlorianMichael
17f57f0c41
Update Via* libraries 2024-05-26 17:40:21 +02:00
FlorianMichael
c1a34f3d7f
Make ClassLoaderPriorityUtil print warnings
Makes it more obvious that jars are overridden because people tend to forget about it leading to random issues later
2024-05-26 16:21:58 +02:00
FlorianMichael
07f25f8e26
Change some injection names 2024-05-26 16:04:43 +02:00
FlorianMichael
ef469dcd26
[ci skip] Add 1.20.6 TODO 2024-05-26 15:54:56 +02:00
FlorianMichael
8f9ab00b94
Handle more 1.20.3->.5 changes 2024-05-26 15:52:34 +02:00
FlorianMichael
277f483b6a
Make UPDATE_INSTRUCTIONS.md clearer 2024-05-26 15:52:07 +02:00
Felix14_v2
0cf982fec3
Update russian translations (#422) 2024-05-26 13:09:32 +02:00
FlorianMichael
06c6cd024a
Mark internals and make initializing private where possible 2024-05-26 01:28:53 +02:00
FlorianMichael
203585875f
Handle auto read changes in 1.20.3->.5 2024-05-26 01:16:03 +02:00
FlorianMichael
17ecf0c736
Add ProtocolTranslator#getTargetVersion with channel argument 2024-05-25 22:22:44 +02:00
FlorianMichael
73d21aaf2c
Rename storage classes and move init into ViaFabricPlusProtocol 2024-05-25 22:15:44 +02:00
FlorianMichael
a6327fb588
Fix method sorting 2024-05-25 21:48:32 +02:00
FlorianMichael
e01522c2fa
Move game options fix into correct package 2024-05-25 21:47:03 +02:00
FlorianMichael
473fe49b69
Update repository artifact in DEVELOPER_API.md 2024-05-25 21:18:32 +02:00
FlorianMichael
249d46470b
Update VV API usage 2024-05-23 15:02:41 +02:00
FlorianMichael
6b115b712f
Fix invalid javadoc for ProtocolTranslator#getPlayNetworkUserConnection 2024-05-20 17:52:18 +02:00
FlorianMichael
2e0018b7bc
Update VV, validate namespace correctly in registry 2024-05-20 00:26:56 +02:00
FlorianMichael
458b4daf15
Rewrite 1.14.4 enchantment registry properly
Adds a 1.14 enchantment name -> 1.20.5 enchantment element registry to validate enchantments and get the correct one even when names change.
2024-05-20 00:17:05 +02:00
RaphiMC
90dfd7d4a2
Update ViaBedrock API usage 2024-05-19 16:50:05 +02:00
FlorianMichael
e4f91d4808
Override packet handler 2024-05-19 14:37:27 +02:00
FlorianMichael
ad75e36213
Rename tracker package and ViaFabricPlusProtocol protocol 2024-05-19 02:09:19 +02:00
RaphiMC
68c6310c9d
Fix code style 2024-05-19 00:09:24 +02:00
FlorianMichael
f471068696
Add networking fixes to 1.20.3->.5 2024-05-18 19:02:12 +02:00
FlorianMichael
d69a3a9bd2
Update TODO list
remove entries which are either now resolved or were wrong in the first place
2024-05-18 18:18:44 +02:00
FlorianMichael
cd3caa9156
Load settings earlier again, post load target version
Fixes GeneralSettings#emulateInventoryActionsInAlphaVersions not working because config loading was AFTER loading Via providers, target version loading has to be late, so it catches up versions added by Via* addons and VFP (auto protocol)
2024-05-18 14:30:02 +02:00
RaphiMC
aef746bbb2
Fix Via maven server issues by pinning snapshots 2024-05-18 11:32:48 +02:00
RaphiMC
f5315892fd
Remove offset when checking for sneaking collision
Fixes #401
2024-05-18 11:02:24 +02:00
RaphiMC
30e97c41f4
Code cleanup 2024-05-18 00:00:27 +02:00
FlorianMichael
6c372c2127
Update ViaLegacy API usage 2024-05-17 23:54:44 +02:00
FlorianMichael
d9458d1fb7
Move out debug mixin into integration, cleanup mixins json 2024-05-17 23:06:17 +02:00
FlorianMichael
1f5ac05fcf
Add flow control handler for Via
Adds missing flow control handler to ViaVersion's pipeline to fix several issues related to the configuration state
Closes https://github.com/ViaVersion/ViaFabricPlus/issues/414
2024-05-17 22:56:27 +02:00
FlorianMichael
56ee795de5
Only show world seed in debug hud when existent in current version 2024-05-17 21:44:09 +02:00
FlorianMichael
38580e328c
Port to upstream changes 2024-05-17 21:39:54 +02:00
FlorianMichael
cd41e5cab3
Bump version to 3.3.0-SNAPSHOT 2024-05-17 21:39:21 +02:00
FlorianMichael
7c5ce2cc71
Update VV version reference 2024-05-16 20:18:33 +02:00
Blay
14e1fcbeca
Update polish translations (#417) 2024-05-16 20:11:36 +02:00
FlorianMichael
c20d900aff
Update Via* libraries
Set to last snapshot versions before v5 since migration will take some time
2024-05-14 19:44:17 +02:00
FlorianMichael
d2b834a058
Add debug setting to print networking errors to log files 2024-05-14 19:43:53 +02:00
FlorianMichael
41a2139a98
Add german translation for new setting 2024-05-09 20:02:48 +02:00
Pablo Herrera
60a26d2bb1
Add 1.7->1.8 tablist behaviour and layout (#411)
* Implement legacy tablist functionality

* Address review comments (squashed)

* Minor changes following code review
2024-05-09 19:57:02 +02:00
FlorianMichael
4a6d0b56a0
Bump version to 3.2.2-SNAPSHOT 2024-05-05 17:40:15 +02:00
FlorianMichael
78094303be
Release 3.2.1 2024-05-05 17:32:24 +02:00
FlorianMichael
adf5ab9456 Update Via* 2024-05-05 17:28:05 +02:00
Joseph Burton
9c78a71d40
Use ModifyExpressionValue in MixinStringHelper (#406) 2024-05-05 12:19:10 +02:00
FlorianMichael
223e1591f9 Update ViaBedrock (1.20.80)
Currently not working due to internal pipeline changes 1.20.5 did, will fix that at another point.
2024-05-04 22:22:15 +02:00
FlorianMichael
f84865645e Use HandlerNames class for MC pipeline constants 2024-05-01 02:11:35 +02:00
FlorianMichael
f7eef8fd4b 1.20.6 2024-04-29 17:40:17 +02:00
Blay
9dfcd7db1a
Update polish translations (#402) 2024-04-29 12:36:57 +02:00
FlorianMichael
f5cad41e90 Bump version to 3.2.1-SNAPSHOT 2024-04-28 15:24:24 +02:00
FlorianMichael
efd70ead90 Fix build script
Closes https://github.com/ViaVersion/ViaFabricPlus/issues/400
2024-04-28 15:15:49 +02:00
FlorianMichael
d4070e0a03 Release 3.2.0 2024-04-28 14:57:42 +02:00
FlorianMichael
27a5da4690 Merge remote-tracking branch 'origin/update/1.20.5' into update/1.20.5 2024-04-28 14:57:09 +02:00
FlorianMichael
53d2fa65d4 Update Fabric API 2024-04-28 14:56:52 +02:00
RaphiMC
89515390c2
Code cleanup 2024-04-28 14:54:08 +02:00
FlorianMichael
4ef493a68b Update ItemRegistryDiff 2024-04-28 14:52:31 +02:00
RaphiMC
a6fd03ded2
Code cleanup 2024-04-28 14:44:50 +02:00
FlorianMichael
f45895c547 Move PostViaVersionLoadCallback into ViaFabricPlusVLLoader 2024-04-28 14:35:03 +02:00
FlorianMichael
38a900c78d Unify tracking tag names 2024-04-28 13:28:08 +02:00
FlorianMichael
8b26d75717 Port pre 1.11 negative item count fix 2024-04-28 12:39:16 +02:00
FlorianMichael
ff942ccf09 Cleanup code 2024-04-28 12:36:15 +02:00
FlorianMichael
642b4de7a0 Port attribute modifier tooltip fix 2024-04-27 23:19:59 +02:00
FlorianMichael
624b6dcbca Port custom payload fixes on protocol level 2024-04-27 23:19:42 +02:00
FlorianMichael
712d8bbba7 Restructure item fix loading
Also fixes the loading behaviour of PostViaVersionLoadCallback to actually getting fired after Via is fully loaded. Adding VB back since VAF requires it (for now).
2024-04-27 18:42:08 +02:00
FlorianMichael
7fc46c4854 Port ingame hud changes 2024-04-27 00:48:37 +02:00
FlorianMichael
5ef8d1bae4 Fix possible NPE in 32k enchantment fix 2024-04-27 00:43:08 +02:00
FlorianMichael
6e21d8d946 Use VFPListEntry abstraction for protocol screens 2024-04-27 00:04:47 +02:00
FlorianMichael
6fa75395d5 Add VFPList abstraction layer to globally remove selection highlighting 2024-04-26 23:57:33 +02:00
FlorianMichael
964d3fbd48 Don't rely on deprecated API method 2024-04-26 23:45:55 +02:00
FlorianMichael
a2f159cb58 Removed outdated translation key 2024-04-26 23:41:32 +02:00
FlorianMichael
710d1bd251 Port 32k enchantments fix as well 2024-04-26 23:32:12 +02:00
FlorianMichael
f45b2b0047 Remove ViaBackwards dependency
Not needed anymore since snapshots won't be supported from now on due to VVs new release cycle.
2024-04-26 21:13:31 +02:00
FlorianMichael
ae2c6da14c Merge branch 'refs/heads/main' into update/1.20.5
# Conflicts:
#	gradle.properties
2024-04-26 20:47:43 +02:00
FlorianMichael
05dfdc30d3 Delete VV version rename patch
Now merged into VV which will be public by friday.
2024-04-25 20:44:02 +02:00
FlorianMichael
971ad3241a Merge branch 'refs/heads/main' into update/1.20.5
# Conflicts:
#	.github/workflows/build.yml
#	gradle.properties
#	src/main/resources/assets/viafabricplus/lang/zh_tw.json
2024-04-25 20:43:00 +02:00
RaphiMC
185e24e5c8
Workaround for data loading race condition 2024-04-24 23:04:00 +02:00
RaphiMC
bc8682b010
Don't clear entity eye height and attachment points 2024-04-24 16:36:04 +02:00
RaphiMC
e7f9188fbf
Remove TODO 2024-04-24 15:10:09 +02:00
RaphiMC
1422464052
Fix version comparison 2024-04-24 14:48:09 +02:00
RaphiMC
862d040e48
Remove TODO 2024-04-23 22:20:49 +02:00
RaphiMC
37b8c8e52e
Disable strict error handling 2024-04-23 22:02:12 +02:00
RaphiMC
39e8866548
Readd item attribute fixes on protocol level 2024-04-23 20:25:26 +02:00
RaphiMC
6dd2cd6894
Rename item-tool-components.json 2024-04-23 20:25:10 +02:00
RaphiMC
57564c8488
Move 1.19.4 material data to json file 2024-04-22 22:17:03 +02:00
RaphiMC
b41474f257
Readd item data fixes on protocol level 2024-04-22 20:15:33 +02:00
RaphiMC
b3b66c0526
Add interaction range and step height fixes 2024-04-20 19:31:04 +02:00
RaphiMC
796ae671b8
Readd 1.7 step height change 2024-04-19 18:30:03 +02:00
RaphiMC
f6282d34d9
Fix villager trading emulation 2024-04-19 16:47:01 +02:00
RaphiMC
c1a90bd329
Readd clientside fixes packet handling 2024-04-19 16:34:31 +02:00
RaphiMC
1a6937a398
Fix GH action 2024-04-17 23:15:13 +02:00
RaphiMC
8c64fa74a4
Initial 1.20.5 port 2024-04-17 23:13:28 +02:00
217 changed files with 9935 additions and 3422 deletions

View File

@ -9,11 +9,11 @@ jobs:
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v3
- name: Set up JDK 17
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
java-version: 21
check-latest: true
- name: Build with Gradle
run: ./gradlew build

View File

@ -16,13 +16,13 @@ ViaFabricPlus is a deep integration of ViaVersion on the Fabric platform, it imp
At the time of writing, VFP is the only protocol translation platform for the client with which you can play on all Minecraft multiplayer versions with many QoL features and get the feel of the old versions.
## Supported Server versions
- Release (1.0.0 - 1.20.5)
- Release (1.0.0 - 1.21)
- 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.20.70 ([Some features are missing](https://github.com/RaphiMC/ViaBedrock#features))
- Bedrock Edition 1.21.0 ([Some features are missing](https://github.com/RaphiMC/ViaBedrock#features))
## For players
- Tutorial for installing and using the mod can be found [here](docs/USAGE.md)

View File

@ -20,10 +20,6 @@ configurations {
repositories {
mavenCentral()
maven {
name = "Jitpack"
url = "https://jitpack.io"
}
maven {
name = "ViaVersion"
url = "https://repo.viaversion.com"
@ -32,14 +28,14 @@ repositories {
name = "Lenni0451"
url = "https://maven.lenni0451.net/everything"
}
maven {
name = "TerraformersMC"
url = "https://maven.terraformersmc.com/releases"
}
maven {
name = "OpenCollab Snapshots"
url = "https://repo.opencollab.dev/maven-snapshots/"
}
maven {
name = "TerraformersMC"
url = "https://maven.terraformersmc.com/releases"
}
}
loom {
@ -69,7 +65,6 @@ dependencies {
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"
}
@ -98,8 +93,10 @@ dependencies {
// Fabric's jar in jar system doesn't support transitive dependencies, so we have to manually add them
afterEvaluate {
configurations.jij.incoming.resolutionResult.allDependencies {
dependencies.include(dependencies.implementation(dependencies.compileOnlyApi(requested.toString())))
configurations.jij.incoming.resolutionResult.allDependencies.each {
dependencies.include(dependencies.implementation(dependencies.compileOnlyApi(it.requested.toString()) {
transitive = false
}))
}
}
}
@ -125,8 +122,8 @@ String latestCommitHash() {
java {
withSourcesJar()
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
jar {

View File

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

View File

@ -57,14 +57,19 @@ ViaFabricPlus uses Gradle, to make sure that it is installed properly you can ch
=> 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,
From experience, most changes are related to either movement or networking,
packages like `gametest` or `server` can be skipped usually when updating. It's important to always diff code inside
the `net.minecraft.client` package as well as `net.minecraft.world` package, as these are the most likely to contain changes. (Mojang mappings)
7. Update protocol constants in the `ViaFabricPlusProtocol` class
8. 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
9. Run the game and check all GUIs and other visuals for issues.
10. 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!
11. Increment the version number in `gradle.properties` by at least a minor version (e.g. 1.0.0 -> 1.1.0)
12. Create a pull request and wait for it to be reviewed and merged.
13. You're done, congrats!
## Git branches
- `main`: The main branch, this is where all changes are merged into

View File

@ -3,27 +3,27 @@ org.gradle.jvmargs=-Xmx8G
org.gradle.parallel=true
# Minecraft/Fabric
minecraft_version=1.20.4
yarn_mappings=1.20.4+build.3
loader_version=0.15.10
fabric_api_version=0.97.0+1.20.4
minecraft_version=1.21
yarn_mappings=1.21+build.1
loader_version=0.15.11
fabric_api_version=0.100.1+1.21
# Project Details
mod_version=3.1.1
mod_version=3.4.2-SNAPSHOT
maven_group=de.florianmichael
archives_base_name=ViaFabricPlus
# ViaVersion Libraries
viaversion_version=4.10.0
viabackwards_version=4.10.0
vialegacy_version=2.2.22
viaaprilfools_version=2.0.11
vialoader_version=2.2.13
viaversion_version=5.0.1
viabackwards_version=5.0.1
vialegacy_version=3.0.1
viaaprilfools_version=3.0.1-SNAPSHOT
vialoader_version=3.0.1
# RaphiMC Libraries
minecraftauth_version=4.0.0
viabedrock_version=0.0.6-SNAPSHOT
viabedrock_version=0.0.9-SNAPSHOT
raknet_transport_version=1.0.0.CR3-SNAPSHOT
# Lenni0451 Libraries
@ -31,5 +31,5 @@ reflect_version=1.3.2
mcping_version=1.4.0
# Misc Libraries
mod_menu_version=9.0.0
mod_menu_version=11.0.0-beta.1
classic4j_version=2.0.2

View File

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

View File

@ -1,7 +1,7 @@
# Deploys the latest stable JDK 17 available and sets it to default without having to manually specify it here,
# Deploys the latest stable JDK 21 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 17.0.10-tem
- sdk use java 17.0.10-tem
- sdk install java 21.0.3-tem
- sdk use java 21.0.3-tem

View File

@ -33,19 +33,49 @@ import java.io.File;
import java.util.concurrent.CompletableFuture;
/*
* TODO | Port 1.20.6
* - ClientPlayerInteractionManager#interactBlockInternal added new condition
* - MouseHandling changed (not sure if relevant)
* - Command arguments (Probably not everything worth, but least them with nbt)
* - Entity attachment calculation got changed completely
* - Particle handling has slightly changed
*
* TODO | Port 1.21
* - LocalPlayer#aiStep nether portal logic
* - Camera logic got changed again
* - ExtraCodecs#QUATERNIONF_COMPONENTS
* - Armadilllo removedd shouldPanic
* - AbstractHorse canWearBodyArmor->canUseSlot
* - horses getInvColumns behaviour
* - Wolf hasArmor -> interactions
* - HangingEntity, ItemFrame, Painting, PrimedTnt
* - Villager offers are server only now
* - Player#attack
* - Boat floating and interaction
* - Entity collide functions and interaction
* - LivingEntity#getBlockSpeedFactor, decreaseAirSupply, knockback, travel, getPreciseBodyRotation,
* - Mob interact
* - AxeItem playerHasShieldUseIntent new
* - BucketItem, ChorusFruit, FoodOnAStickItem, KnowledgeBookItem, TridentItem,
* - CakeBlock creative check in interaction
* - Jukebox overrides new interaction function
* - SignBlock, TntBlock creative check
* - Check item rarity values
* - ItemStack count max changed in codec
* - SolidBucketItem useOn
*
* 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)
* - Check if MixinPlayerScreenHandler.injectTransferSlot is needed? Check git log
* - Via: 1.13 -> 1.12.2 block entities recode
*
* TODO | Movement
* - Collision hit boxes has been changed (https://github.com/ViaVersion/ViaFabricPlus/issues/195)
* - Blip-jumping is not supported in <= 1.13.2 (https://github.com/ViaVersion/ViaFabricPlus/issues/225)
* - Older versions don't clamp positions when teleporting (Is this important?)
* - 1.8 lava movement
* - 1.13.2 water movement
*/
public class ViaFabricPlus {
@ -59,21 +89,20 @@ public class ViaFabricPlus {
private CompletableFuture<Void> loadingFuture;
@SuppressWarnings("ResultOfMethodCallIgnored")
public void init() {
directory.mkdir();
ClassLoaderPriorityUtil.loadOverridingJars(directory); // Load overriding jars first so other code can access the new classes
ClientsideFixes.init(); // Init clientside related fixes
loadingFuture = ProtocolTranslator.init(directory); // Init ViaVersion protocol translator platform
settingsManager = new SettingsManager();
saveManager = new SaveManager(settingsManager);
ClientsideFixes.init(); // Init clientside related fixes
loadingFuture = ProtocolTranslator.init(directory); // Init ViaVersion protocol translator platform
// Block game loading until ViaVersion has loaded
PostGameLoadCallback.EVENT.register(() -> {
loadingFuture.join();
saveManager.init();
saveManager.postInit();
});
}

View File

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

View File

@ -31,18 +31,22 @@ import de.florianmichael.viafabricplus.fixes.versioned.visual.FootStepParticle1_
import de.florianmichael.viafabricplus.injection.access.IClientConnection;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.BedrockSettings;
import de.florianmichael.viafabricplus.util.DataCustomPayload;
import net.minecraft.block.*;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.FontStorage;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ServerAddress;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.RegistryByteBuf;
import net.minecraft.registry.Registries;
import net.raphimc.viaaprilfools.api.AprilFoolsProtocolVersion;
import net.raphimc.viabedrock.api.BedrockProtocolVersion;
import net.raphimc.viabedrock.protocol.data.ProtocolConstants;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.data.ClassicProtocolExtension;
import net.raphimc.vialegacy.protocols.classic.protocolc0_28_30toc0_28_30cpe.storage.ExtensionProtocolMetadataStorage;
import net.raphimc.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 java.util.Map;
import java.util.Objects;
@ -58,19 +62,19 @@ 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<PacketByteBuf>> PENDING_EXECUTION_TASKS = new ConcurrentHashMap<>();
private static final Map<String, Consumer<RegistryByteBuf>> PENDING_EXECUTION_TASKS = new ConcurrentHashMap<>();
/**
* This identifier is an internal identifier that is used to identify packets that are sent by ViaFabricPlus
* This identifier is an internal identifier used to identify packets that are sent by ViaFabricPlus
*/
public static final String PACKET_SYNC_IDENTIFIER = UUID.randomUUID() + ":" + UUID.randomUUID();
/**
* This identifier is an internal identifier used to store the item count in <= 1.10 to implement negative item counts
* This is an incremental index used for tablist entries to implement FIFO behavior <= 1.7
*/
public static final String ITEM_COUNT_NBT_TAG = "VFP_1_10_ItemCount_" + System.currentTimeMillis();
public static int GLOBAL_TABLIST_INDEX = 0;
public static void init() {
static {
// Register additional CPE features
CPEAdditions.modifyMappings();
@ -114,10 +118,22 @@ public class ClientsideFixes {
if (newVersion.olderThanOrEqualTo(LegacyProtocolVersion.c0_28toc0_30)) {
GridItemSelectionScreen.INSTANCE.itemGrid = null;
}
// Reload sound system when switching between 3D Shareware and normal versions
if (oldVersion.equals(AprilFoolsProtocolVersion.s3d_shareware) || newVersion.equals(AprilFoolsProtocolVersion.s3d_shareware)) {
MinecraftClient.getInstance().getSoundManager().reloadSounds();
}
}));
// Register the footstep particle
FootStepParticle1_12_2.init();
// Register the custom payload packet for sync tasks
DataCustomPayload.init();
}
public static void init() {
// Calls the static block
}
/**
@ -167,19 +183,20 @@ public class ClientsideFixes {
* @param task The task to execute
* @return The uuid of the task
*/
public static String executeSyncTask(final Consumer<PacketByteBuf> task) {
public static String executeSyncTask(final Consumer<RegistryByteBuf> task) {
final String uuid = UUID.randomUUID().toString();
PENDING_EXECUTION_TASKS.put(uuid, task);
return uuid;
}
@ApiStatus.Internal
public static void handleSyncTask(final PacketByteBuf buf) {
final String uuid = buf.readString();
if (PENDING_EXECUTION_TASKS.containsKey(uuid)) {
MinecraftClient.getInstance().execute(() -> { // Execute the task on the main thread
final var task = PENDING_EXECUTION_TASKS.remove(uuid);
task.accept(buf);
task.accept(new RegistryByteBuf(buf, MinecraftClient.getInstance().getNetworkHandler().getRegistryManager()));
});
}
}

View File

@ -23,6 +23,8 @@ import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.event.ChangeProtocolVersionCallback;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.EntityAttachmentType;
import net.minecraft.entity.EntityAttachments;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityType;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
@ -42,105 +44,107 @@ public class EntityDimensionDiff {
*/
private static final Map<EntityType<?>, Map<ProtocolVersion, EntityDimensions>> ENTITY_DIMENSIONS = linkedHashMap(
EntityType.WITHER, linkedHashMap(
ProtocolVersion.v1_7_6, EntityDimensions.changing(0.9F, 4.0F),
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, EntityDimensions.changing(0.3F, 0.7F),
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, EntityDimensions.changing(0.4F, 1.8F),
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, EntityDimensions.changing(0.6F, 1.8F),
ProtocolVersion.v1_8, EntityDimensions.fixed(EntityType.ZOMBIE.getDimensions().width, EntityType.ZOMBIE.getDimensions().height),
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, EntityDimensions.changing(0.3F, 0.4F),
ProtocolVersion.v1_7_6, EntityDimensions.changing(0.3F, 0.7F),
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, EntityDimensions.changing(1.4F, 1.72F),
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, EntityDimensions.changing(0.6F, 0.8F),
ProtocolVersion.v1_7_6, EntityDimensionsBuilder.create(EntityType.OCELOT).withChangingDimensions(0.6F, 0.8F).build(),
ProtocolVersion.v1_8, EntityType.OCELOT.getDimensions()
),
EntityType.BOAT, linkedHashMap(
ProtocolVersion.v1_8, EntityDimensions.changing(1.5F, 0.6F),
ProtocolVersion.v1_8, EntityDimensionsBuilder.create(EntityType.BOAT).withChangingDimensions(1.5F, 0.6F).build(),
ProtocolVersion.v1_9, EntityType.BOAT.getDimensions()
),
EntityType.CREEPER, linkedHashMap(
ProtocolVersion.v1_8, EntityDimensions.changing(0.6F, 1.8F),
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, EntityDimensions.changing(1.4F, 2.9F),
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, EntityDimensions.changing(0.6F, 1.8F),
ProtocolVersion.v1_8, EntityDimensions.changing(0.6F, 1.95F),
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, EntityDimensions.changing(0.72F, 2.16F),
ProtocolVersion.v1_7_6, EntityDimensions.changing(0.72F, 2.34F),
ProtocolVersion.v1_8, EntityDimensions.changing(0.72F, 2.535F),
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, EntityDimensions.changing(0.9F, 1.3F),
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, EntityDimensions.changing(1.4F, 1.6F),
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, EntityDimensions.changing(0.9F, 1.3F),
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, EntityDimensions.changing(0.6F, 0.7F),
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, EntityDimensions.changing(0.95F, 0.95F),
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, EntityDimensions.changing(0.6F, 1.8F),
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, EntityDimensions.changing(0.8F, 0.8F),
ProtocolVersion.v1_8, EntityDimensions.changing(0.6F, 0.8F),
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, EntityDimensions.changing(0.3125F, 0.3125F),
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, EntityDimensions.changing(0.5F, 0.5F),
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, EntityDimensions.changing(2F, 2F),
ProtocolVersion.v1_14, EntityType.SLIME.getDimensions()
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, EntityDimensions.changing(2F, 2F),
ProtocolVersion.v1_14, EntityType.MAGMA_CUBE.getDimensions()
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, EntityDimensions.changing(0.3F, 0.5F),
LegacyProtocolVersion.c0_28toc0_30, EntityDimensionsBuilder.create(EntityType.ARROW).withChangingDimensions(0.3F, 0.5F).build(),
LegacyProtocolVersion.a1_0_15, EntityType.ARROW.getDimensions()
)
);
@ -162,7 +166,7 @@ public class EntityDimensionDiff {
}
public static void init() {
// Loads the class and triggers the static initializer.
// Calls the static block
}
/**
@ -208,4 +212,49 @@ public class EntityDimensionDiff {
return closestDimensions;
}
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;
}
}
}

View File

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

View File

@ -25,6 +25,7 @@ import net.minecraft.GameVersion;
import net.minecraft.SaveVersion;
import net.minecraft.SharedConstants;
import net.minecraft.resource.ResourceType;
import org.jetbrains.annotations.ApiStatus;
import java.util.Date;
import java.util.HashMap;
@ -38,7 +39,8 @@ public class ResourcePackHeaderDiff {
private final static Map<ProtocolVersion, GameVersion> GAME_VERSION_DIFF = new HashMap<>();
static {
registerVersion(ProtocolVersion.v1_20_5, 32, "1.20.5");
registerVersion(ProtocolVersion.v1_21, 34, "1.21");
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");
@ -84,6 +86,7 @@ public class ResourcePackHeaderDiff {
/**
* Checks if the registry is outdated.
*/
@ApiStatus.Internal
public static void checkOutdated() {
for (ProtocolVersion version : ProtocolVersion.getProtocols()) {
if (version.isSnapshot()) continue;

View File

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

View File

@ -20,76 +20,79 @@
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("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));
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));
private final String id;
private final RegistryKey<BannerPattern> pattern;
private final String[] recipePattern;
private ItemStack baseStack;
BannerPattern_1_13_2(String id) {
BannerPattern_1_13_2(final RegistryKey<BannerPattern> pattern) {
this.recipePattern = new String[3];
this.baseStack = ItemStack.EMPTY;
this.id = id;
this.pattern = pattern;
}
BannerPattern_1_13_2(String id, ItemStack baseStack) {
this(id);
BannerPattern_1_13_2(final RegistryKey<BannerPattern> pattern, final ItemStack baseStack) {
this(pattern);
this.baseStack = baseStack;
}
BannerPattern_1_13_2(String id, String recipe1, String recipe2, String recipe3) {
this(id);
BannerPattern_1_13_2(final RegistryKey<BannerPattern> pattern, final String recipe1, final String recipe2, final String recipe3) {
this(pattern);
this.recipePattern[0] = recipe1;
this.recipePattern[1] = recipe2;
this.recipePattern[2] = recipe3;
}
public String getId() {
return this.id;
public RegistryKey<BannerPattern> getKey() {
return this.pattern;
}
public boolean isCraftable() {

View File

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

View File

@ -0,0 +1,82 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.fixes.versioned;
import com.viaversion.viaversion.util.Key;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.registry.RegistryKey;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
public class Enchantments1_14_4 {
private static final Map<String, RegistryKey<Enchantment>> ENCHANTMENT_REGISTRY = new HashMap<>();
static {
ENCHANTMENT_REGISTRY.put("protection", Enchantments.PROTECTION);
ENCHANTMENT_REGISTRY.put("fire_protection", Enchantments.FIRE_PROTECTION);
ENCHANTMENT_REGISTRY.put("feather_falling", Enchantments.FEATHER_FALLING);
ENCHANTMENT_REGISTRY.put("blast_protection", Enchantments.BLAST_PROTECTION);
ENCHANTMENT_REGISTRY.put("projectile_protection", Enchantments.PROJECTILE_PROTECTION);
ENCHANTMENT_REGISTRY.put("respiration", Enchantments.RESPIRATION);
ENCHANTMENT_REGISTRY.put("aqua_affinity", Enchantments.AQUA_AFFINITY);
ENCHANTMENT_REGISTRY.put("thorns", Enchantments.THORNS);
ENCHANTMENT_REGISTRY.put("depth_strider", Enchantments.DEPTH_STRIDER);
ENCHANTMENT_REGISTRY.put("frost_walker", Enchantments.FROST_WALKER);
ENCHANTMENT_REGISTRY.put("binding_curse", Enchantments.BINDING_CURSE);
ENCHANTMENT_REGISTRY.put("sharpness", Enchantments.SHARPNESS);
ENCHANTMENT_REGISTRY.put("smite", Enchantments.SMITE);
ENCHANTMENT_REGISTRY.put("bane_of_arthropods", Enchantments.BANE_OF_ARTHROPODS);
ENCHANTMENT_REGISTRY.put("knockback", Enchantments.KNOCKBACK);
ENCHANTMENT_REGISTRY.put("fire_aspect", Enchantments.FIRE_ASPECT);
ENCHANTMENT_REGISTRY.put("looting", Enchantments.LOOTING);
ENCHANTMENT_REGISTRY.put("sweeping", Enchantments.SWEEPING_EDGE);
ENCHANTMENT_REGISTRY.put("efficiency", Enchantments.EFFICIENCY);
ENCHANTMENT_REGISTRY.put("silk_touch", Enchantments.SILK_TOUCH);
ENCHANTMENT_REGISTRY.put("unbreaking", Enchantments.UNBREAKING);
ENCHANTMENT_REGISTRY.put("fortune", Enchantments.FORTUNE);
ENCHANTMENT_REGISTRY.put("power", Enchantments.POWER);
ENCHANTMENT_REGISTRY.put("punch", Enchantments.PUNCH);
ENCHANTMENT_REGISTRY.put("flame", Enchantments.FLAME);
ENCHANTMENT_REGISTRY.put("infinity", Enchantments.INFINITY);
ENCHANTMENT_REGISTRY.put("luck_of_the_sea", Enchantments.LUCK_OF_THE_SEA);
ENCHANTMENT_REGISTRY.put("lure", Enchantments.LURE);
ENCHANTMENT_REGISTRY.put("loyalty", Enchantments.LOYALTY);
ENCHANTMENT_REGISTRY.put("impaling", Enchantments.IMPALING);
ENCHANTMENT_REGISTRY.put("riptide", Enchantments.RIPTIDE);
ENCHANTMENT_REGISTRY.put("channeling", Enchantments.CHANNELING);
ENCHANTMENT_REGISTRY.put("multishot", Enchantments.MULTISHOT);
ENCHANTMENT_REGISTRY.put("quick_charge", Enchantments.QUICK_CHARGE);
ENCHANTMENT_REGISTRY.put("piercing", Enchantments.PIERCING);
ENCHANTMENT_REGISTRY.put("mending", Enchantments.MENDING);
ENCHANTMENT_REGISTRY.put("vanishing_curse", Enchantments.VANISHING_CURSE);
}
public static Optional<RegistryKey<Enchantment>> getOrEmpty(final String identifier) {
if (identifier == null) {
return Optional.empty();
}
return Optional.ofNullable(ENCHANTMENT_REGISTRY.get(Key.stripMinecraftNamespace(identifier)));
}
}

View File

@ -22,8 +22,8 @@ package de.florianmichael.viafabricplus.fixes.versioned.classic;
import com.viaversion.viaversion.api.connection.UserConnection;
import io.netty.buffer.ByteBuf;
import net.lenni0451.reflect.Enums;
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 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 java.util.Arrays;
import java.util.HashMap;

View File

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

View File

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

View File

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

View File

@ -21,10 +21,10 @@ package de.florianmichael.viafabricplus.fixes.versioned.visual;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.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 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 de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
@ -62,11 +62,11 @@ public class ArmorHudEmulation1_8 {
});
}
private static void sendArmorUpdate(final UserConnection userConnection) throws Exception {
private static void sendArmorUpdate(final UserConnection userConnection) {
// Calculate the armor points.
int armor = 0;
for (final ItemStack stack : MinecraftClient.getInstance().player.getInventory().armor) {
armor += ArmorType.findByType(Registries.ITEM.getId(stack.getItem()).toString()).getArmorPoints();
armor += ArmorTypes1_8.findByType(Registries.ITEM.getId(stack.getItem()).toString()).getArmorPoints();
}
// We only want to update the armor points if they actually changed.
@ -75,16 +75,16 @@ public class ArmorHudEmulation1_8 {
}
previousArmorPoints = armor;
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);
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);
}
}

View File

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

View File

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

View File

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

View File

@ -27,7 +27,7 @@ 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.DefaultParticleType;
import net.minecraft.particle.SimpleParticleType;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
@ -36,7 +36,8 @@ import net.minecraft.util.math.Vec3d;
public class FootStepParticle1_12_2 extends SpriteBillboardParticle {
public static int ID;
public static final Identifier ID = Identifier.of("viafabricplus", "footstep");
public static int RAW_ID;
protected FootStepParticle1_12_2(ClientWorld clientWorld, double x, double y, double z) {
super(clientWorld, x, y, z);
@ -71,22 +72,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).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();
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);
}
public static void init() {
final DefaultParticleType footStepType = FabricParticleTypes.simple(true);
final SimpleParticleType footStepType = FabricParticleTypes.simple(true);
Registry.register(Registries.PARTICLE_TYPE, new Identifier("viafabricplus", "footstep"), footStepType);
Registry.register(Registries.PARTICLE_TYPE, ID, footStepType);
ParticleFactoryRegistry.getInstance().register(footStepType, FootStepParticle1_12_2.Factory::new);
ID = Registries.PARTICLE_TYPE.getRawId(footStepType);
RAW_ID = Registries.PARTICLE_TYPE.getRawId(footStepType);
}
public static class Factory implements ParticleFactory<DefaultParticleType> {
public static class Factory implements ParticleFactory<SimpleParticleType> {
private final SpriteProvider spriteProvider;
@ -95,7 +96,7 @@ public class FootStepParticle1_12_2 extends SpriteBillboardParticle {
}
@Override
public Particle createParticle(DefaultParticleType parameters, ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ) {
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)) {
throw new UnsupportedOperationException("FootStepParticle is not supported on versions newer than 1.12.2");
}

View File

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

View File

@ -0,0 +1,28 @@
/*
* 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.StorableObject;
public class SnowTrackerc0_30cpe implements StorableObject {
public static final SnowTrackerc0_30cpe INSTANCE = new SnowTrackerc0_30cpe();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -19,12 +19,8 @@
package de.florianmichael.viafabricplus.injection.access;
public interface IItemStack {
public interface IPlayerListEntry {
boolean viaFabricPlus$has1_10Tag();
int viaFabricPlus$get1_10Count();
void viaFabricPlus$set1_10Count(final int count);
int viaFabricPlus$getIndex();
}

View File

@ -0,0 +1,26 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.access;
public interface IPlayerListHud {
void viaFabricPlus$setMaxPlayers(final int maxPlayers);
}

View File

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

View File

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

View File

@ -0,0 +1,46 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.base.connect;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import net.minecraft.client.option.GameOptions;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(GameOptions.class)
public abstract class MixinGameOptions {
@Shadow
public boolean useNativeTransport;
/**
* @author RK_01
* @reason Needed as an indicator if the client wants to ping a server or connect to a server
*/
@Overwrite
public boolean shouldUseNativeTransport() {
if (!this.useNativeTransport) {
ViaFabricPlus.global().getLogger().error("Native transport is disabled, but enabling it anyway since we use it as an indicator if the client wants to ping a server or connect to a server.");
}
return true;
}
}

View File

@ -17,22 +17,25 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.viabedrock;
package de.florianmichael.viafabricplus.injection.mixin.base.integration;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viafabricplus.fixes.tracker.JoinGameDataTracker;
import net.raphimc.viabedrock.protocol.BedrockProtocol;
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;
@Mixin(value = BedrockProtocol.class, remap = false)
public abstract class MixinBedrockProtocol {
@Mixin(ClientConnection.class)
public abstract class MixinClientConnection {
@Inject(method = "init", at = @At("RETURN"))
private void hookStorages(UserConnection user, CallbackInfo ci) {
user.put(new JoinGameDataTracker(user));
@Inject(method = "exceptionCaught", at = @At("HEAD"))
private void printNetworkingErrors(ChannelHandlerContext context, Throwable ex, CallbackInfo ci) {
if (DebugSettings.global().printNetworkingErrorsToLogs.getValue()) {
ViaFabricPlus.global().getLogger().error("An exception occurred while handling a packet", ex);
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -20,15 +20,14 @@
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.fixes.ClientsideFixes;
import de.florianmichael.viafabricplus.injection.access.IPerformanceLog;
import de.florianmichael.viafabricplus.injection.access.IMultiValueDebugSampleLogImpl;
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.PerformanceLog;
import net.minecraft.util.profiler.MultiValueDebugSampleLogImpl;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@ -44,8 +43,8 @@ public abstract class MixinMultiplayerServerListPinger {
return 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(argsOnly = true) ServerInfo serverInfo) {
@Redirect(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, @Local(argsOnly = true) ServerInfo serverInfo) {
final IServerInfo mixinServerInfo = (IServerInfo) serverInfo;
if (mixinServerInfo.viaFabricPlus$forcedVersion() != null && !mixinServerInfo.viaFabricPlus$passedDirectConnectScreen()) {
@ -53,11 +52,11 @@ public abstract class MixinMultiplayerServerListPinger {
// So we can create a dummy instance, store the forced version in it and later destroy the instance again
// To avoid any side effects, we also support cases where a mod is also creating a PerformanceLog instance
if (packetSizeLog == null) {
packetSizeLog = new PerformanceLog();
packetSizeLog = new MultiValueDebugSampleLogImpl(1);
}
// Attach the forced version to the PerformanceLog instance
((IPerformanceLog) packetSizeLog).viaFabricPlus$setForcedVersion(mixinServerInfo.viaFabricPlus$forcedVersion());
((IMultiValueDebugSampleLogImpl) packetSizeLog).viaFabricPlus$setForcedVersion(mixinServerInfo.viaFabricPlus$forcedVersion());
mixinServerInfo.viaFabricPlus$passDirectConnectScreen(false);
}

View File

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

View File

@ -0,0 +1,59 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.compat.fabricapi;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import de.florianmichael.viafabricplus.ViaFabricPlus;
import de.florianmichael.viafabricplus.fixes.versioned.visual.FootStepParticle1_12_2;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import net.fabricmc.fabric.impl.registry.sync.RegistrySyncManager;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Map;
@Mixin(RegistrySyncManager.class)
public abstract class MixinRegistrySyncManager {
@WrapOperation(method = "createAndPopulateRegistryMap", at = @At(value = "INVOKE", target = "Lnet/minecraft/registry/Registry;getId(Ljava/lang/Object;)Lnet/minecraft/util/Identifier;"), require = 0)
private static Identifier skipFootStepParticle(Registry instance, Object t, Operation<Identifier> original) {
final Identifier id = original.call(instance, t);
if (id == FootStepParticle1_12_2.ID) {
return null;
} else {
return id;
}
}
@Inject(method = "checkRemoteRemap", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;error(Ljava/lang/String;)V", ordinal = 0), cancellable = true, remap = false)
private static void ignoreFabricSyncErrors(Map<Identifier, Object2IntMap<Identifier>> map, CallbackInfo ci) {
if (DebugSettings.global().ignoreFabricSyncErrors.getValue()) {
ViaFabricPlus.global().getLogger().warn("Ignoring missing registries from Fabric API");
ci.cancel();
}
}
}

View File

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

View File

@ -26,7 +26,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
/*
* JsonWebToken is used by MinecraftAuth and since it's using Java services, it's not working with the fabric loader
* JsonWebToken is used by MinecraftAuth, and since it's using Java services, it's not working with the fabric loader,
* So we have to change all services usages by using the normal Java API
*/
@Mixin(value = Classes.class, remap = false)

View File

@ -26,13 +26,13 @@ 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;"))
@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<?> spi) {
return new GsonDeserializer<>();
}

View File

@ -27,12 +27,12 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
// Lithium is overriding the sorting with an optimized implementation
// https://github.com/CaffeineMC/lithium-fabric/blob/develop/src/main/java/me/jellysquid/mods/lithium/mixin/entity/collisions/movement/EntityMixin.java#L54
// https://github.com/CaffeineMC/lithium-fabric/blob/develop/src/main/java/me/jellysquid/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 = "lithiumCollideMultiAxisMovement", at = @At(value = "INVOKE", target = "Ljava/lang/Math;abs(D)D", ordinal = 0), remap = false)
@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;

View File

@ -19,8 +19,7 @@
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.settings.impl.DebugSettings;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ChatInputSuggestor;
import net.minecraft.client.gui.widget.TextFieldWidget;
@ -89,7 +88,7 @@ public abstract class MixinChatInputSuggestor {
@Unique
private boolean viaFabricPlus$cancelTabComplete() {
return ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_12_2) && this.textField.getText().startsWith("/");
return DebugSettings.global().legacyTabCompletions.isEnabled() && this.textField.getText().startsWith("/");
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,101 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.client.sound.StaticSound;
import net.raphimc.viaaprilfools.api.AprilFoolsProtocolVersion;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import javax.sound.sampled.AudioFormat;
import java.nio.ByteBuffer;
@Mixin(StaticSound.class)
public abstract class MixinStaticSound {
@Shadow
@Final
private AudioFormat format;
@Inject(method = "<init>", at = @At("RETURN"))
private void modifyBuffer(ByteBuffer sample, AudioFormat format, CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().equals(AprilFoolsProtocolVersion.s3d_shareware)) {
this.viaFabricPlus$apply8BitSound(sample);
}
}
@Unique
private void viaFabricPlus$apply8BitSound(final ByteBuffer byteBuffer) {
if (byteBuffer == null) {
return;
}
if (this.format.getChannels() == 1) {
this.viaFabricPlus$apply8BitMono(byteBuffer);
} else {
this.viaFabricPlus$apply8BitStereo(byteBuffer);
}
}
@Unique
private void viaFabricPlus$apply8BitMono(final ByteBuffer byteBuffer) {
short short2 = 0;
int integer3 = 0;
while (byteBuffer.hasRemaining()) {
if (integer3 == 0) {
byteBuffer.mark();
short2 = (short) (byteBuffer.getShort() & 0xFFFFFFFC);
byteBuffer.reset();
integer3 = 15;
} else {
--integer3;
}
byteBuffer.putShort(short2);
}
byteBuffer.flip();
}
@Unique
private void viaFabricPlus$apply8BitStereo(final ByteBuffer byteBuffer) {
short short2 = 0;
short short3 = 0;
int integer4 = 0;
while (byteBuffer.hasRemaining()) {
if (integer4 == 0) {
byteBuffer.mark();
short2 = (short) (byteBuffer.getShort() & 0xFFFFFFFC);
short3 = (short) (byteBuffer.getShort() & 0xFFFFFFFC);
byteBuffer.reset();
integer4 = 15;
} else {
--integer4;
}
byteBuffer.putShort(short2);
byteBuffer.putShort(short3);
}
byteBuffer.flip();
}
}

View File

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

View File

@ -17,38 +17,29 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
import de.florianmichael.viafabricplus.fixes.viaversion.SnowTrackerc0_30cpe;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.item.ArmorMaterials;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.biome.Biome;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
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.Redirect;
@Mixin(ArmorMaterials.class)
public abstract class MixinArmorMaterials {
@Mixin(WorldRenderer.class)
public abstract class MixinWorldRenderer {
@Shadow
@Final
private int durabilityMultiplier;
@Redirect(method = "getDurability", at = @At(value = "FIELD", target = "Lnet/minecraft/item/ArmorMaterials;durabilityMultiplier:I"))
private int changeDurabilityMultiplier(ArmorMaterials instance) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) {
if (instance == ArmorMaterials.LEATHER) {
return 3;
} else if (instance == ArmorMaterials.CHAIN || instance == ArmorMaterials.GOLD) {
return 6;
} else if (instance == ArmorMaterials.IRON) {
return 12;
} else if (instance == ArmorMaterials.DIAMOND) {
return 24;
@Redirect(method = "renderWeather", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/biome/Biome;getPrecipitation(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/world/biome/Biome$Precipitation;"))
private Biome.Precipitation forceSnow(Biome instance, BlockPos pos) {
if (ProtocolTranslator.getTargetVersion().equals(LegacyProtocolVersion.c0_30cpe)) {
if (ProtocolTranslator.getPlayNetworkUserConnection().has(SnowTrackerc0_30cpe.class)) {
return Biome.Precipitation.SNOW;
}
}
return this.durabilityMultiplier;
return instance.getPrecipitation(pos);
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -291,7 +291,7 @@ public abstract class MixinBoatEntity extends VehicleEntity {
@Inject(method = "updatePassengerPosition", at = @At(value = "HEAD"), cancellable = true)
private void updatePassengerPosition1_8(Entity passenger, PositionUpdater positionUpdater, CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
final Vec3d newPosition = new Vec3d(EntityRidingOffsetsPre1_20_2.getMountedHeightOffset(this, passenger)).add(this.getPos());
final Vec3d newPosition = EntityRidingOffsetsPre1_20_2.getMountedHeightOffset(this, passenger).add(this.getPos());
positionUpdater.accept(passenger, newPosition.x, newPosition.y + EntityRidingOffsetsPre1_20_2.getHeightOffset(passenger), newPosition.z);
ci.cancel();
}

View File

@ -24,23 +24,28 @@ import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.mojang.authlib.GameProfile;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.Types;
import de.florianmichael.viafabricplus.injection.access.IClientConnection;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import de.florianmichael.viafabricplus.util.EnchantmentUtil;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.input.Input;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.Entity;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.network.packet.Packet;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.math.MathHelper;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialegacy.protocols.release.protocol1_6_1to1_5_2.Protocol1_6_1to1_5_2;
import net.raphimc.vialegacy.protocols.release.protocol1_6_1to1_5_2.ServerboundPackets1_5_2;
import net.raphimc.vialegacy.protocol.release.r1_5_2tor1_6_1.Protocolr1_5_2Tor1_6_1;
import net.raphimc.vialegacy.protocol.release.r1_5_2tor1_6_1.packet.ServerboundPackets1_5_2;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@ -48,7 +53,6 @@ import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@SuppressWarnings("ConstantValue")
@Mixin(value = ClientPlayerEntity.class, priority = 2000)
public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity {
@ -73,6 +77,23 @@ public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity
@Final
public ClientPlayNetworkHandler networkHandler;
@Shadow
public abstract void setClientPermissionLevel(int clientPermissionLevel);
@Redirect(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getAttributeValue(Lnet/minecraft/registry/entry/RegistryEntry;)D"))
private double handleSwiftSneakClientside(ClientPlayerEntity instance, RegistryEntry<EntityAttribute> attribute) {
if (attribute == EntityAttributes.PLAYER_SNEAKING_SPEED && ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_5)) {
return MathHelper.clamp(0.3F + EnchantmentUtil.getEquipmentLevel(Enchantments.SWIFT_SNEAK, this) * 0.15F, 0.0F, 1.0F);
} else {
return instance.getAttributeValue(attribute);
}
}
@WrapWithCondition(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;jump()V"))
private boolean dontJumpBeforeFlying(ClientPlayerEntity instance) {
return ProtocolTranslator.getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_20_5);
}
@Redirect(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;hasVehicle()Z", ordinal = 0))
private boolean removeVehicleRequirement(ClientPlayerEntity instance) {
return ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_20) && instance.hasVehicle();
@ -181,12 +202,19 @@ public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity
return ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_12_2) && self.isTouchingWater();
}
@Inject(method = "init", at = @At("RETURN"))
private void setOpLevel4(CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
this.setClientPermissionLevel(4);
}
}
@Redirect(method = "sendMovementPackets", at = @At(value = "FIELD", target = "Lnet/minecraft/client/network/ClientPlayerEntity;ticksSinceLastPositionPacketSent:I", ordinal = 0))
private int moveLastPosPacketIncrement(ClientPlayerEntity instance) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
return ticksSinceLastPositionPacketSent - 1; // Reverting original operation
return this.ticksSinceLastPositionPacketSent - 1; // Reverting original operation
} else {
return ticksSinceLastPositionPacketSent;
return this.ticksSinceLastPositionPacketSent;
}
}
@ -202,22 +230,22 @@ public abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity
if (DebugSettings.global().sendIdlePacket.isEnabled()) {
return !isOnGround();
} else {
return lastOnGround;
return this.lastOnGround;
}
}
@Redirect(method = "tick", slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;hasVehicle()Z")), at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;)V", ordinal = 0))
private void modifyPositionPacket(ClientPlayNetworkHandler instance, Packet<?> packet) throws Exception {
private void modifyPositionPacket(ClientPlayNetworkHandler instance, Packet<?> packet) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_5_2)) {
final PacketWrapper playerPosition = PacketWrapper.create(ServerboundPackets1_5_2.PLAYER_POSITION_AND_ROTATION, ((IClientConnection) this.networkHandler.getConnection()).viaFabricPlus$getUserConnection());
playerPosition.write(Type.DOUBLE, this.getVelocity().x); // x
playerPosition.write(Type.DOUBLE, -999.0D); // y
playerPosition.write(Type.DOUBLE, -999.0D); // stance
playerPosition.write(Type.DOUBLE, this.getVelocity().z); // z
playerPosition.write(Type.FLOAT, this.getYaw()); // yaw
playerPosition.write(Type.FLOAT, this.getPitch()); // pitch
playerPosition.write(Type.BOOLEAN, this.isOnGround()); // onGround
playerPosition.scheduleSendToServer(Protocol1_6_1to1_5_2.class);
final PacketWrapper movePlayerPosRot = PacketWrapper.create(ServerboundPackets1_5_2.MOVE_PLAYER_POS_ROT, ((IClientConnection) this.networkHandler.getConnection()).viaFabricPlus$getUserConnection());
movePlayerPosRot.write(Types.DOUBLE, this.getVelocity().x); // x
movePlayerPosRot.write(Types.DOUBLE, -999.0D); // y
movePlayerPosRot.write(Types.DOUBLE, -999.0D); // stance
movePlayerPosRot.write(Types.DOUBLE, this.getVelocity().z); // z
movePlayerPosRot.write(Types.FLOAT, this.getYaw()); // yaw
movePlayerPosRot.write(Types.FLOAT, this.getPitch()); // pitch
movePlayerPosRot.write(Types.BOOLEAN, this.isOnGround()); // onGround
movePlayerPosRot.scheduleSendToServer(Protocolr1_5_2Tor1_6_1.class);
return;
}
instance.sendPacket(packet);

View File

@ -38,8 +38,8 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.World;
import org.joml.Vector3f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@ -47,6 +47,8 @@ import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@SuppressWarnings("ConstantValue")
@Mixin(Entity.class)
public abstract class MixinEntity implements IEntity {
@ -70,22 +72,63 @@ public abstract class MixinEntity implements IEntity {
public abstract void setVelocity(Vec3d velocity);
@Shadow
protected abstract Vector3f getPassengerAttachmentPos(Entity passenger, EntityDimensions dimensions, float scaleFactor);
protected abstract Vec3d getPassengerAttachmentPos(Entity passenger, EntityDimensions dimensions, float scaleFactor);
@Shadow
public abstract World getWorld();
@Shadow
public abstract boolean isOnGround();
@Shadow
public abstract float getStepHeight();
@Unique
private boolean viaFabricPlus$isInLoadedChunkAndShouldTick;
@Inject(method = "getRidingOffset", at = @At("HEAD"), cancellable = true)
private void getRidingOffset1_20_1(Entity vehicle, CallbackInfoReturnable<Float> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20)) {
cir.setReturnValue((float) EntityRidingOffsetsPre1_20_2.getHeightOffset((Entity) (Object) this));
@Inject(method = "adjustMovementForCollisions(Lnet/minecraft/util/math/Vec3d;)Lnet/minecraft/util/math/Vec3d;", at = @At("HEAD"), cancellable = true)
private void use1_20_6StepCollisionCalculation(Vec3d movement, CallbackInfoReturnable<Vec3d> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_5)) {
final Entity thiz = (Entity) (Object) this;
final Box box = this.getBoundingBox();
final List<VoxelShape> collisions = this.getWorld().getEntityCollisions(thiz, box.stretch(movement));
Vec3d adjustedMovement = movement.lengthSquared() == 0D ? movement : Entity.adjustMovementForCollisions(thiz, movement, box, this.getWorld(), collisions);
final boolean changedX = movement.x != adjustedMovement.x;
final boolean changedY = movement.y != adjustedMovement.y;
final boolean changedZ = movement.z != adjustedMovement.z;
final boolean mayTouchGround = this.isOnGround() || changedY && movement.y < 0D;
if (this.getStepHeight() > 0F && mayTouchGround && (changedX || changedZ)) {
Vec3d vec3d2 = Entity.adjustMovementForCollisions(thiz, new Vec3d(movement.x, this.getStepHeight(), movement.z), box, this.getWorld(), collisions);
Vec3d vec3d3 = Entity.adjustMovementForCollisions(thiz, new Vec3d(0D, this.getStepHeight(), 0D), box.stretch(movement.x, 0D, movement.z), this.getWorld(), collisions);
if (vec3d3.y < this.getStepHeight()) {
Vec3d vec3d4 = Entity.adjustMovementForCollisions(thiz, new Vec3d(movement.x, 0D, movement.z), box.offset(vec3d3), this.getWorld(), collisions).add(vec3d3);
if (vec3d4.horizontalLengthSquared() > vec3d2.horizontalLengthSquared()) {
vec3d2 = vec3d4;
}
}
if (vec3d2.horizontalLengthSquared() > adjustedMovement.horizontalLengthSquared()) {
adjustedMovement = vec3d2.add(Entity.adjustMovementForCollisions(thiz, new Vec3d(0D, -vec3d2.y + movement.y, 0D), box.offset(vec3d2), this.getWorld(), collisions));
}
}
cir.setReturnValue(adjustedMovement);
}
}
@Redirect(method = "getPassengerRidingPos", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getPassengerAttachmentPos(Lnet/minecraft/entity/Entity;Lnet/minecraft/entity/EntityDimensions;F)Lorg/joml/Vector3f;"))
private Vector3f getPassengerRidingPos1_20_1(Entity instance, Entity passenger, EntityDimensions dimensions, float scaleFactor) {
@Redirect(method = "updatePassengerPosition(Lnet/minecraft/entity/Entity;Lnet/minecraft/entity/Entity$PositionUpdater;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getVehicleAttachmentPos(Lnet/minecraft/entity/Entity;)Lnet/minecraft/util/math/Vec3d;"))
private Vec3d use1_20_1RidingOffset(Entity instance, Entity vehicle) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20)) {
return EntityRidingOffsetsPre1_20_2.getMountedHeightOffset(instance, passenger);
return new Vec3d(0, -EntityRidingOffsetsPre1_20_2.getHeightOffset(instance), 0);
} else {
return instance.getVehicleAttachmentPos(vehicle);
}
}
@Redirect(method = "getPassengerRidingPos", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getPassengerAttachmentPos(Lnet/minecraft/entity/Entity;Lnet/minecraft/entity/EntityDimensions;F)Lnet/minecraft/util/math/Vec3d;"))
private Vec3d getPassengerRidingPos1_20_1(Entity instance, Entity passenger, EntityDimensions dimensions, float scaleFactor) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20)) {
return EntityRidingOffsetsPre1_20_2.getMountedHeightOffset(instance, passenger).rotateY(-instance.getYaw() * (float) (Math.PI / 180));
} else {
return getPassengerAttachmentPos(passenger, dimensions, scaleFactor);
}

View File

@ -19,20 +19,26 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.fixes.versioned.visual.EntityRidingOffsetsPre1_20_2;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
import de.florianmichael.viafabricplus.util.EnchantmentUtil;
import net.minecraft.block.BlockState;
import net.minecraft.block.TrapdoorBlock;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.*;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.registry.tag.FluidTags;
import net.minecraft.registry.tag.TagKey;
@ -42,9 +48,9 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.raphimc.viabedrock.api.BedrockProtocolVersion;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import org.joml.Vector3f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@ -67,26 +73,44 @@ public abstract class MixinLivingEntity extends Entity {
protected abstract boolean canEnterTrapdoor(BlockPos pos, BlockState state);
@Shadow
public abstract boolean hasStatusEffect(StatusEffect effect);
private int jumpingCooldown;
@Shadow
private int jumpingCooldown;
public abstract boolean hasStatusEffect(RegistryEntry<StatusEffect> effect);
public MixinLivingEntity(EntityType<?> type, World world) {
super(type, world);
}
@Inject(method = "getRidingOffset", at = @At("HEAD"), cancellable = true)
private void getRidingOffset1_20_1(Entity vehicle, CallbackInfoReturnable<Float> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20)) {
cir.setReturnValue((float) EntityRidingOffsetsPre1_20_2.getHeightOffset(this));
@Redirect(method = "travel", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;getAttributeValue(Lnet/minecraft/registry/entry/RegistryEntry;)D"))
private double handleDepthStriderClientside(LivingEntity instance, RegistryEntry<EntityAttribute> attribute) {
if (attribute == EntityAttributes.GENERIC_WATER_MOVEMENT_EFFICIENCY && ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_5)) {
return Math.min(EnchantmentUtil.getEquipmentLevel(Enchantments.DEPTH_STRIDER, (LivingEntity) (Object) this), 3) / 3F;
} else {
return instance.getAttributeValue(attribute);
}
}
@Redirect(method = "getPassengerRidingPos", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;getPassengerAttachmentPos(Lnet/minecraft/entity/Entity;Lnet/minecraft/entity/EntityDimensions;F)Lorg/joml/Vector3f;"))
private Vector3f getPassengerRidingPos1_20_1(LivingEntity instance, Entity entity, EntityDimensions entityDimensions, float v) {
@Inject(method = "getVelocityMultiplier", at = @At("HEAD"), cancellable = true)
private void getVelocityMultiplier1_20_6(CallbackInfoReturnable<Float> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_5)) {
cir.setReturnValue(this.isOnSoulSpeedBlock() && EnchantmentUtil.getEquipmentLevel(Enchantments.SOUL_SPEED, (LivingEntity) (Object) this) > 0 ? 1F : super.getVelocityMultiplier());
}
}
@ModifyExpressionValue(method = "tickStatusEffects", at = @At(value = "CONSTANT", args = "intValue=4"))
private int changeParticleDensity(int original) {
if (ProtocolTranslator.getTargetVersion().olderThan(ProtocolVersion.v1_20_5)) {
return 2;
} else {
return original;
}
}
@Redirect(method = "getPassengerRidingPos", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/LivingEntity;getPassengerAttachmentPos(Lnet/minecraft/entity/Entity;Lnet/minecraft/entity/EntityDimensions;F)Lnet/minecraft/util/math/Vec3d;"))
private Vec3d getPassengerRidingPos1_20_1(LivingEntity instance, Entity entity, EntityDimensions entityDimensions, float v) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20)) {
return EntityRidingOffsetsPre1_20_2.getMountedHeightOffset(instance, entity);
return EntityRidingOffsetsPre1_20_2.getMountedHeightOffset(instance, entity).rotateY(-instance.getYaw() * (float) (Math.PI / 180));
} else {
return getPassengerAttachmentPos(entity, entityDimensions, v);
}
@ -127,7 +151,7 @@ public abstract class MixinLivingEntity extends Entity {
}
@Redirect(method = "travel", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;isChunkLoaded(Lnet/minecraft/util/math/BlockPos;)Z"))
private boolean modify1_13LoadedCheck(World instance, BlockPos blockPos) {
private boolean modifyLoadedCheck(World instance, BlockPos blockPos) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_13_2)) {
return this.getWorld().isChunkLoaded(blockPos) && instance.getChunkManager().isChunkLoaded(blockPos.getX() >> 4, blockPos.getZ() >> 4);
} else {
@ -141,7 +165,7 @@ public abstract class MixinLivingEntity extends Entity {
}
@Redirect(method = "travel",
slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/entity/effect/StatusEffects;DOLPHINS_GRACE:Lnet/minecraft/entity/effect/StatusEffect;")),
slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/entity/effect/StatusEffects;DOLPHINS_GRACE:Lnet/minecraft/registry/entry/RegistryEntry;")),
at = @At(value = "FIELD", target = "Lnet/minecraft/entity/LivingEntity;horizontalCollision:Z", ordinal = 0))
private boolean disableClimbing(LivingEntity instance) {
return ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_13_2) && instance.horizontalCollision;
@ -198,7 +222,7 @@ public abstract class MixinLivingEntity extends Entity {
}
@Inject(method = "getPreferredEquipmentSlot", at = @At("HEAD"), cancellable = true)
private static void removeShieldSlotPreference(ItemStack stack, CallbackInfoReturnable<EquipmentSlot> cir) {
private void removeShieldSlotPreference(ItemStack stack, CallbackInfoReturnable<EquipmentSlot> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_9_3) && stack.isOf(Items.SHIELD)) {
cir.setReturnValue(EquipmentSlot.MAINHAND);
}
@ -220,15 +244,8 @@ public abstract class MixinLivingEntity extends Entity {
}
}
@Inject(method = "<init>", at = @At("RETURN"))
private void modify1_7StepHeight(EntityType<? extends LivingEntity> type, World world, CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_7_6)) {
this.setStepHeight(0.5F);
}
}
@Inject(method = "tickMovement", at = @At("HEAD"))
private void removeJumpDelay1_0(CallbackInfo ci) {
private void removeJumpDelay(CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThan(LegacyProtocolVersion.r1_0_0tor1_0_1)) {
this.jumpingCooldown = 0;
}
@ -249,4 +266,13 @@ public abstract class MixinLivingEntity extends Entity {
}
}
@Unique
protected boolean isOnSoulSpeedBlock() {
if ((Object) this instanceof PlayerEntity player && player.getAbilities().flying) {
return false;
}
return this.getWorld().getBlockState(this.getVelocityAffectingPos()).isIn(BlockTags.SOUL_SPEED_BLOCKS);
}
}

View File

@ -25,9 +25,13 @@ import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
import de.florianmichael.viafabricplus.util.EnchantmentUtil;
import net.minecraft.block.BlockState;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.*;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeInstance;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffects;
@ -37,6 +41,7 @@ import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ElytraItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.sound.SoundEvent;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
@ -50,7 +55,6 @@ import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@SuppressWarnings("ConstantValue")
@Mixin(PlayerEntity.class)
public abstract class MixinPlayerEntity extends LivingEntity {
@ -63,13 +67,13 @@ public abstract class MixinPlayerEntity extends LivingEntity {
@Shadow
@Final
private PlayerInventory inventory;
PlayerInventory inventory;
@Unique
private static final EntityDimensions viaFabricPlus$sneaking_dimensions_v1_13_2 = EntityDimensions.changing(0.6F, 1.65F);
private static final EntityDimensions viaFabricPlus$sneaking_dimensions_v1_13_2 = EntityDimensions.changing(0.6F, 1.65F).withEyeHeight(1.54F);
@Unique
private static final SoundEvent viaFabricPlus$oof_hurt = SoundEvent.of(new Identifier("viafabricplus", "oof.hurt"));
private static final SoundEvent viaFabricPlus$oof_hurt = SoundEvent.of(Identifier.of("viafabricplus", "oof.hurt"));
@Unique
public boolean viaFabricPlus$isSprinting;
@ -78,6 +82,38 @@ public abstract class MixinPlayerEntity extends LivingEntity {
super(entityType, world);
}
@Redirect(method = "getBlockBreakingSpeed", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/attribute/EntityAttributeInstance;getValue()D"))
private double handleAquaAffinityClientside(EntityAttributeInstance instance) {
if (instance.getAttribute() == EntityAttributes.PLAYER_SUBMERGED_MINING_SPEED && ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_5)) {
return EnchantmentUtil.getEquipmentLevel(Enchantments.AQUA_AFFINITY, this) <= 0 ? 0.2F : 1F;
} else {
return instance.getValue();
}
}
@Redirect(method = "getBlockBreakingSpeed", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;getAttributeValue(Lnet/minecraft/registry/entry/RegistryEntry;)D"))
private double handleEfficiencyClientside(PlayerEntity instance, RegistryEntry<EntityAttribute> attribute) {
if (attribute == EntityAttributes.PLAYER_MINING_EFFICIENCY && ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_5)) {
final int effLevel = EnchantmentUtil.getEquipmentLevel(Enchantments.EFFICIENCY, this);
if (effLevel > 0 && !this.getMainHandStack().isEmpty()) {
return effLevel * effLevel + 1;
} else {
return 0;
}
} else {
return instance.getAttributeValue(attribute);
}
}
@ModifyConstant(method = "isSpaceAroundPlayerEmpty", constant = @Constant(doubleValue = 9.999999747378752E-6 /* 1.0E-5F */))
private double removeOffsetWhenCheckingSneakingCollision(double constant) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_3)) {
return 0;
} else {
return constant;
}
}
@Redirect(method = "getMaxRelativeHeadRotation", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;isBlocking()Z"))
private boolean dontModifyHeadRotationWhenBlocking(PlayerEntity instance) {
return ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_20_2) && instance.isBlocking();
@ -102,9 +138,9 @@ public abstract class MixinPlayerEntity extends LivingEntity {
return ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_15_2);
}
@Redirect(method = "checkFallFlying", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;hasStatusEffect(Lnet/minecraft/entity/effect/StatusEffect;)Z"))
private boolean allowElytraWhenLevitating(PlayerEntity instance, StatusEffect statusEffect) {
return ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_15_2) && instance.hasStatusEffect(statusEffect);
@Redirect(method = "checkFallFlying", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;hasStatusEffect(Lnet/minecraft/registry/entry/RegistryEntry;)Z"))
private boolean allowElytraWhenLevitating(PlayerEntity instance, RegistryEntry<StatusEffect> registryEntry) {
return ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_15_2) && instance.hasStatusEffect(registryEntry);
}
@Inject(method = "checkFallFlying", at = @At("HEAD"), cancellable = true)
@ -121,15 +157,6 @@ public abstract class MixinPlayerEntity extends LivingEntity {
}
}
@ModifyConstant(method = "getActiveEyeHeight", constant = @Constant(floatValue = 1.27f))
private float modifySneakEyeHeight(float prevEyeHeight) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_13_2)) {
return 1.54F;
} else {
return prevEyeHeight;
}
}
@Inject(method = "updatePose", at = @At("HEAD"), cancellable = true)
private void onUpdatePose(CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_13_2)) {
@ -152,7 +179,7 @@ public abstract class MixinPlayerEntity extends LivingEntity {
}
}
@Inject(method = "getDimensions", at = @At("HEAD"), cancellable = true)
@Inject(method = "getBaseDimensions", at = @At("HEAD"), cancellable = true)
private void modifyDimensions(EntityPose pose, CallbackInfoReturnable<EntityDimensions> cir) {
if (pose == EntityPose.CROUCHING) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
@ -164,7 +191,7 @@ public abstract class MixinPlayerEntity extends LivingEntity {
}
@Redirect(method = "adjustMovementForSneaking", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;getStepHeight()F"))
private float modifyStepHeight1_10(PlayerEntity instance) {
private float modifyStepHeight(PlayerEntity instance) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_10)) {
return 1.0F;
} else {
@ -179,16 +206,20 @@ public abstract class MixinPlayerEntity extends LivingEntity {
}
}
@Inject(method = "getHurtSound", at = @At("HEAD"), cancellable = true)
private void replaceSound(DamageSource source, CallbackInfoReturnable<SoundEvent> cir) {
if (VisualSettings.global().replaceHurtSoundWithOOFSound.isEnabled()) {
cir.setReturnValue(viaFabricPlus$oof_hurt);
@Redirect(method = "getBlockBreakingSpeed", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;hasStatusEffect(Lnet/minecraft/registry/entry/RegistryEntry;)Z"))
private boolean changeSpeedCalculation(PlayerEntity instance, RegistryEntry<StatusEffect> statusEffect, @Local LocalFloatRef f) {
final boolean hasMiningFatigue = instance.hasStatusEffect(statusEffect);
if (hasMiningFatigue && ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_7_6)) {
f.set(f.get() * (1.0F - (this.getStatusEffect(StatusEffects.MINING_FATIGUE).getAmplifier() + 1) * 0.2F));
if (f.get() < 0) f.set(0);
return false; // disable original code
}
return hasMiningFatigue;
}
@Inject(method = "getBlockBreakingSpeed", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/effect/StatusEffectUtil;hasHaste(Lnet/minecraft/entity/LivingEntity;)Z", shift = At.Shift.BEFORE))
private void changeSpeedCalculation(BlockState block, CallbackInfoReturnable<Float> cir, @Local LocalFloatRef f) {
final int efficiency = EnchantmentHelper.getEfficiency(this);
final int efficiency = EnchantmentUtil.getEquipmentLevel(Enchantments.EFFICIENCY, this);
if (efficiency <= 0) return;
final float speed = this.inventory.getBlockBreakingSpeed(block);
@ -208,21 +239,10 @@ public abstract class MixinPlayerEntity extends LivingEntity {
}
}
@Redirect(method = "getBlockBreakingSpeed", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;hasStatusEffect(Lnet/minecraft/entity/effect/StatusEffect;)Z"))
private boolean changeSpeedCalculation(PlayerEntity instance, StatusEffect statusEffect, @Local LocalFloatRef f) {
final boolean hasMiningFatigue = instance.hasStatusEffect(statusEffect);
if (hasMiningFatigue && ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_7_6)) {
f.set(f.get() * (1.0F - (this.getStatusEffect(StatusEffects.MINING_FATIGUE).getAmplifier() + 1) * 0.2F));
if (f.get() < 0) f.set(0);
return false; // disable original code
}
return hasMiningFatigue;
}
@Inject(method = "getReachDistance", at = @At("RETURN"), cancellable = true)
private static void modifyReachDistance(boolean creative, CallbackInfoReturnable<Float> cir) {
if (ProtocolTranslator.getTargetVersion().olderThan(LegacyProtocolVersion.r1_0_0tor1_0_1) && !creative) {
cir.setReturnValue(4F);
@Inject(method = "getHurtSound", at = @At("HEAD"), cancellable = true)
private void replaceSound(DamageSource source, CallbackInfoReturnable<SoundEvent> cir) {
if (VisualSettings.global().replaceHurtSoundWithOOFSound.isEnabled()) {
cir.setReturnValue(viaFabricPlus$oof_hurt);
}
}

View File

@ -22,7 +22,6 @@ package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.entity.passive.SquidEntity;
import net.minecraft.entity.player.PlayerEntity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@ -31,8 +30,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(SquidEntity.class)
public abstract class MixinSquidEntity {
@Inject(method = "canBeLeashedBy", at = @At("HEAD"), cancellable = true)
private void cancelLeashing(PlayerEntity player, CallbackInfoReturnable<Boolean> cir) {
@Inject(method = "canBeLeashed", at = @At("HEAD"), cancellable = true)
private void cancelLeashing(CallbackInfoReturnable<Boolean> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_16_4)) {
cir.setReturnValue(false);
}

View File

@ -20,8 +20,10 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.entity;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.fixes.tracker.WolfHealthTracker;
import de.florianmichael.viafabricplus.fixes.viaversion.WolfHealthTracker1_14_4;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.FoodComponent;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.mob.Angerable;
import net.minecraft.entity.passive.TameableEntity;
@ -50,7 +52,7 @@ public abstract class MixinWolfEntity extends TameableEntity implements Angerabl
public abstract DyeColor getCollarColor();
@Shadow
public abstract void setCollarColor(DyeColor color);
protected abstract void setCollarColor(DyeColor color);
protected MixinWolfEntity(EntityType<? extends TameableEntity> entityType, World world) {
super(entityType, world);
@ -62,10 +64,11 @@ public abstract class MixinWolfEntity extends TameableEntity implements Angerabl
final ItemStack itemStack = player.getStackInHand(hand);
final Item item = itemStack.getItem();
if (this.isTamed()) {
if (item.isFood()) {
if (item.getFoodComponent().isMeat() && this.viaFabricPlus$getWolfHealth() < 20.0F) {
final FoodComponent foodComponent = itemStack.get(DataComponentTypes.FOOD);
if (foodComponent != null) {
if (this.isBreedingItem(itemStack) && this.viaFabricPlus$getWolfHealth() < 20.0F) {
if (!player.getAbilities().creativeMode) itemStack.decrement(1);
this.heal((float) item.getFoodComponent().getHunger());
this.heal(foodComponent.nutrition());
cir.setReturnValue(ActionResult.SUCCESS);
return;
}
@ -99,7 +102,8 @@ public abstract class MixinWolfEntity extends TameableEntity implements Angerabl
@Unique
private float viaFabricPlus$getWolfHealth() {
return WolfHealthTracker.get(ProtocolTranslator.getPlayNetworkUserConnection()).getWolfHealth(this.getId(), this.getHealth());
return ProtocolTranslator.getPlayNetworkUserConnection().get(WolfHealthTracker1_14_4.class).
getWolfHealth(this.getId(), this.getHealth());
}
}

View File

@ -19,39 +19,29 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.component.type.AttributeModifiersComponent;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.world.World;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ArmorItem.class)
public abstract class MixinArmorItem {
public abstract class MixinArmorItem extends Item {
@Shadow
@Final
private Multimap<EntityAttribute, EntityAttributeModifier> attributeModifiers;
@Unique
private final Multimap<EntityAttribute, EntityAttributeModifier> viaFabricPlus$AttributeModifiers_r1_8 = ImmutableMultimap.of();
public MixinArmorItem(Settings settings) {
super(settings);
}
@Inject(method = "use", at = @At("HEAD"), cancellable = true)
private void disableRightClick(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable<TypedActionResult<ItemStack>> cir) {
@ -60,12 +50,10 @@ public abstract class MixinArmorItem {
}
}
@Redirect(method = "getAttributeModifiers", at = @At(value = "FIELD", target = "Lnet/minecraft/item/ArmorItem;attributeModifiers:Lcom/google/common/collect/Multimap;"))
private Multimap<EntityAttribute, EntityAttributeModifier> changeAttributeModifiers(ArmorItem instance) {
if (DebugSettings.global().replaceAttributeModifiers.isEnabled()) {
return this.viaFabricPlus$AttributeModifiers_r1_8;
} else {
return this.attributeModifiers;
@Inject(method = "getAttributeModifiers", at = @At("HEAD"), cancellable = true)
private void changeAttributeModifiers(CallbackInfoReturnable<AttributeModifiersComponent> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
cir.setReturnValue(super.getAttributeModifiers());
}
}

View File

@ -19,49 +19,18 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import com.google.common.collect.ImmutableSet;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.fixes.data.Material1_19_4;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.*;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.item.AxeItem;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.ActionResult;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Set;
@Mixin(AxeItem.class)
public abstract class MixinAxeItem extends MiningToolItem {
@Unique
private static final Set<Block> viaFabricPlus$effective_blocks_b1_8_1 = ImmutableSet.of(Blocks.OAK_PLANKS, Blocks.BOOKSHELF, Blocks.OAK_LOG, Blocks.CHEST);
@Unique
private static final Set<Block> viaFabricPlus$effective_blocks_r1_16_5 = ImmutableSet.of(Blocks.LADDER, Blocks.SCAFFOLDING, Blocks.OAK_BUTTON, Blocks.SPRUCE_BUTTON, Blocks.BIRCH_BUTTON, Blocks.JUNGLE_BUTTON, Blocks.DARK_OAK_BUTTON, Blocks.ACACIA_BUTTON, Blocks.CRIMSON_BUTTON, Blocks.WARPED_BUTTON);
@Unique
private static final Set<Material1_19_4> viaFabricPlus$effective_materials_r1_16_5 = ImmutableSet.of(Material1_19_4.WOOD, Material1_19_4.NETHER_WOOD, Material1_19_4.PLANT, Material1_19_4.REPLACEABLE_PLANT, Material1_19_4.BAMBOO, Material1_19_4.GOURD);
public MixinAxeItem(float attackDamage, float attackSpeed, ToolMaterial material, TagKey<Block> effectiveBlocks, Settings settings) {
super(attackDamage, attackSpeed, material, effectiveBlocks, settings);
}
@Override
public boolean isSuitableFor(BlockState state) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_16_4)) {
return false;
} else {
return super.isSuitableFor(state);
}
}
public abstract class MixinAxeItem {
@Inject(method = "useOnBlock", at = @At("HEAD"), cancellable = true)
private void disableUse(ItemUsageContext context, CallbackInfoReturnable<ActionResult> cir) {
@ -70,15 +39,4 @@ public abstract class MixinAxeItem extends MiningToolItem {
}
}
@Override
public float getMiningSpeedMultiplier(ItemStack stack, BlockState state) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) {
return viaFabricPlus$effective_blocks_b1_8_1.contains(state.getBlock()) ? this.miningSpeed : 1.0F;
} else if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_16_4)) {
return viaFabricPlus$effective_materials_r1_16_5.contains(Material1_19_4.getMaterial(state)) ? this.miningSpeed : viaFabricPlus$effective_blocks_r1_16_5.contains(state.getBlock()) ? this.miningSpeed : 1.0F;
} else {
return super.getMiningSpeedMultiplier(stack, state);
}
}
}

View File

@ -37,14 +37,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
public abstract class MixinBowItem {
@Inject(method = "getMaxUseTime", at = @At("HEAD"), cancellable = true)
private void makeInstantUsable(CallbackInfoReturnable<Integer> cir) {
private void makeInstantUsable_Time(CallbackInfoReturnable<Integer> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.b1_7tob1_7_3)) {
cir.setReturnValue(0);
}
}
@Inject(method = "getUseAction", at = @At("HEAD"), cancellable = true)
private void makeInstantUsable2(CallbackInfoReturnable<UseAction> cir) {
private void makeInstantUsable_Action(CallbackInfoReturnable<UseAction> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.b1_7tob1_7_3)) {
cir.setReturnValue(UseAction.NONE);
}

View File

@ -30,12 +30,12 @@ import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(BrushItem.class)
public abstract class MixinBrushItem {
@Redirect(method = "getHitResult", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;getReachDistance(Z)F"))
private float modifyReachDistance(boolean creative) {
@Redirect(method = "getHitResult", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;getBlockInteractionRange()D"))
private double modifyReachDistance(PlayerEntity instance) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_2)) {
return 5F;
return 5D;
} else {
return PlayerEntity.getReachDistance(creative);
return instance.getBlockInteractionRange();
}
}

View File

@ -19,21 +19,28 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import de.florianmichael.viafabricplus.injection.access.IItemStack;
import com.viaversion.viaversion.protocols.v1_10to1_11.Protocol1_10To1_11;
import de.florianmichael.viafabricplus.util.ItemUtil;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.Formatting;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(DrawContext.class)
public abstract class MixinDrawContext {
@Unique
private static final String viaFabricPlus$vvIdentifier = "VV|" + Protocol1_10To1_11.class.getSimpleName(); // ItemRewriter#nbtTagName
@Redirect(method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getCount()I"))
private int handleNegativeItemCount(ItemStack instance) {
if (((IItemStack) (Object) instance).viaFabricPlus$has1_10Tag()) {
return ((IItemStack) (Object) instance).viaFabricPlus$get1_10Count();
final NbtCompound tag = ItemUtil.getTagOrNull(instance);
if (tag != null && tag.contains(viaFabricPlus$vvIdentifier)) {
return tag.getInt(viaFabricPlus$vvIdentifier);
} else {
return instance.getCount();
}

View File

@ -22,7 +22,6 @@ package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Equipment;
import net.minecraft.item.Item;
@ -48,7 +47,7 @@ public interface MixinEquipment {
private void cancelArmorSwap(Item item, World world, PlayerEntity user, Hand hand, CallbackInfoReturnable<TypedActionResult<ItemStack>> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_19_3)) {
final ItemStack heldItem = user.getStackInHand(hand);
final EquipmentSlot targetSlot = MobEntity.getPreferredEquipmentSlot(heldItem);
final EquipmentSlot targetSlot = user.getPreferredEquipmentSlot(heldItem);
final ItemStack targetItem = user.getEquippedStack(targetSlot);
if (!targetItem.isEmpty()) {

View File

@ -46,18 +46,21 @@ public abstract class MixinHeldItemRenderer {
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/item/HeldItemRenderer;applyEquipOffset(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/util/Arm;F)V", ordinal = 2, shift = At.Shift.AFTER))
private void transformLegacyBlockAnimations(AbstractClientPlayerEntity player, float tickDelta, float pitch, Hand hand, float swingProgress, ItemStack item, float equipProgress, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) {
final boolean blockHitAnimation = VisualSettings.global().enableBlockHitAnimation.isEnabled();
if (VisualSettings.global().enableSwordBlocking.isEnabled() || blockHitAnimation) {
final Arm arm = hand == Hand.MAIN_HAND ? player.getMainArm() : player.getMainArm().getOpposite();
matrices.translate(arm == Arm.RIGHT ? -0.1F : 0.1F, 0.05F, 0.0F);
if (blockHitAnimation) {
applySwingOffset(matrices, arm, swingProgress);
}
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(-102.25f));
matrices.multiply((arm == Arm.RIGHT ? RotationAxis.POSITIVE_Y : RotationAxis.NEGATIVE_Y).rotationDegrees(13.365f));
matrices.multiply((arm == Arm.RIGHT ? RotationAxis.POSITIVE_Z : RotationAxis.NEGATIVE_Z).rotationDegrees(78.05f));
if (!VisualSettings.global().enableSwordBlocking.isEnabled() && !blockHitAnimation) {
return;
}
final Arm arm = hand == Hand.MAIN_HAND ? player.getMainArm() : player.getMainArm().getOpposite();
if (blockHitAnimation) {
applySwingOffset(matrices, arm, swingProgress);
matrices.translate(arm == Arm.RIGHT ? -0.14F : 0.14F, 0.12F, 0.12F);
} else {
matrices.translate(arm == Arm.RIGHT ? -0.15F : 0.15F, 0.07F, 0.12F);
}
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(-102.25f));
matrices.multiply((arm == Arm.RIGHT ? RotationAxis.POSITIVE_Y : RotationAxis.NEGATIVE_Y).rotationDegrees(13.365f));
matrices.multiply((arm == Arm.RIGHT ? RotationAxis.POSITIVE_Z : RotationAxis.NEGATIVE_Z).rotationDegrees(78.05f));
}
}

View File

@ -1,79 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import com.google.common.collect.ImmutableSet;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.HoeItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.MiningToolItem;
import net.minecraft.item.ToolMaterial;
import net.minecraft.registry.tag.TagKey;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import java.util.Set;
@Mixin(HoeItem.class)
public abstract class MixinHoeItem extends MiningToolItem {
@Unique
private static final Set<Block> viaFabricPlus$effective_blocks_r1_16_5 = ImmutableSet.of(
Blocks.NETHER_WART_BLOCK,
Blocks.WARPED_WART_BLOCK,
Blocks.HAY_BLOCK,
Blocks.DRIED_KELP_BLOCK,
Blocks.TARGET,
Blocks.SHROOMLIGHT,
Blocks.SPONGE,
Blocks.WET_SPONGE,
Blocks.JUNGLE_LEAVES,
Blocks.OAK_LEAVES,
Blocks.SPRUCE_LEAVES,
Blocks.DARK_OAK_LEAVES,
Blocks.ACACIA_LEAVES,
Blocks.BIRCH_LEAVES
);
protected MixinHoeItem(float attackDamage, float attackSpeed, ToolMaterial material, TagKey<Block> effectiveBlocks, Settings settings) {
super(attackDamage, attackSpeed, material, effectiveBlocks, settings);
}
@Override
public boolean isSuitableFor(BlockState state) {
return ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_16_4) && super.isSuitableFor(state);
}
@Override
public float getMiningSpeedMultiplier(ItemStack stack, BlockState state) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_15_2)) {
return 1.0F;
} else if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_16_4)) {
return viaFabricPlus$effective_blocks_r1_16_5.contains(state.getBlock()) ? this.miningSpeed : 1.0F;
} else {
return super.getMiningSpeedMultiplier(stack, state);
}
}
}

View File

@ -1,75 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.CrossbowItem;
import net.minecraft.item.Item;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
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.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Item.class)
public abstract class MixinItem {
@Shadow
@Final
private int maxDamage;
@Shadow
public abstract boolean isFood();
@Redirect(method = {"getMaxDamage", "isDamageable", "getItemBarStep", "getItemBarColor"}, at = @At(value = "FIELD", target = "Lnet/minecraft/item/Item;maxDamage:I"))
private int changeCrossbowDamage(Item instance) {
if (instance instanceof ArmorItem armor && ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) {
// Counterpart in MixinArmorMaterials
return armor.getMaterial().getDurability(armor.getType());
} else if (instance instanceof CrossbowItem && ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_17_1)) {
return 326;
} else {
return maxDamage;
}
}
@Inject(method = "getMaxCount", at = @At("HEAD"), cancellable = true)
private void dontStackFood(CallbackInfoReturnable<Integer> cir) {
if (this.isFood() && ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.b1_7tob1_7_3)) {
cir.setReturnValue(1);
}
}
@ModifyExpressionValue(method = {"use", "finishUsing", "getUseAction", "getMaxUseTime"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;isFood()Z"))
private boolean makeFoodInstantConsumable(boolean original) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.b1_7tob1_7_3)) {
return false;
} else {
return original;
}
}
}

View File

@ -20,8 +20,8 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.fixes.data.Material1_19_4;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.protocoltranslator.impl.ViaFabricPlusMappingDataLoader;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity;
@ -73,7 +73,7 @@ public abstract class MixinItemPlacementContext extends ItemUsageContext {
@Inject(method = "canPlace", at = @At("RETURN"), cancellable = true)
private void canPlace1_12_2(CallbackInfoReturnable<Boolean> cir) {
if (!cir.getReturnValueZ() && ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_12_2)) {
cir.setReturnValue(Material1_19_4.getMaterial(this.getWorld().getBlockState(this.getBlockPos())).equals(Material1_19_4.DECORATION) && Block.getBlockFromItem(this.getStack().getItem()).equals(Blocks.ANVIL));
cir.setReturnValue(ViaFabricPlusMappingDataLoader.getBlockMaterial(this.getWorld().getBlockState(this.getBlockPos()).getBlock()).equals("decoration") && Block.getBlockFromItem(this.getStack().getItem()).equals(Blocks.ANVIL));
}
}

View File

@ -20,66 +20,89 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.injection.access.IItemStack;
import de.florianmichael.viafabricplus.fixes.versioned.Enchantments1_14_4;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.util.ItemUtil;
import net.minecraft.component.ComponentType;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.tooltip.TooltipAppender;
import net.minecraft.item.tooltip.TooltipType;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtList;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.text.Text;
import net.minecraft.util.math.MathHelper;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(value = ItemStack.class, priority = 1)
public abstract class MixinItemStack implements IItemStack {
import java.util.Optional;
import java.util.function.Consumer;
@Mixin(ItemStack.class)
public abstract class MixinItemStack {
@Shadow
public abstract Item getItem();
@Unique
private boolean viaFabricPlus$has1_10Tag;
@Inject(method = "appendTooltip", at = @At("HEAD"), cancellable = true)
private <T extends TooltipAppender> void replaceEnchantmentTooltip(ComponentType<T> componentType, Item.TooltipContext context, Consumer<Text> textConsumer, TooltipType type, CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_14_4)) {
return;
}
@Unique
private int viaFabricPlus$1_10Count;
final NbtCompound tag = ItemUtil.getTagOrNull((ItemStack) (Object) this);
if (tag == null) {
return;
}
if (componentType == DataComponentTypes.ENCHANTMENTS) {
this.viaFabricPlus$appendEnchantments1_14_4("Enchantments", tag, context, textConsumer);
ci.cancel();
} else if (componentType == DataComponentTypes.STORED_ENCHANTMENTS) {
this.viaFabricPlus$appendEnchantments1_14_4("StoredEnchantments", tag, context, textConsumer);
ci.cancel();
}
}
@Redirect(method = "getTooltip",
slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/entity/attribute/EntityAttributes;GENERIC_ATTACK_DAMAGE:Lnet/minecraft/entity/attribute/EntityAttribute;", ordinal = 0)),
at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;getAttributeBaseValue(Lnet/minecraft/entity/attribute/EntityAttribute;)D", ordinal = 0))
private double fixDamageCalculation(PlayerEntity player, EntityAttribute attribute) {
@Redirect(method = "appendAttributeModifierTooltip", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;getAttributeBaseValue(Lnet/minecraft/registry/entry/RegistryEntry;)D", ordinal = 0))
private double removeAttackDamageValueFromCalculation(PlayerEntity instance, RegistryEntry<EntityAttribute> registryEntry) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
return 0;
} else {
return player.getAttributeBaseValue(attribute);
return instance.getAttributeBaseValue(registryEntry);
}
}
@Inject(method = "copy", at = @At("RETURN"))
private void copyViaFabricPlusData(CallbackInfoReturnable<ItemStack> cir) {
final IItemStack mixinItemStack = (IItemStack) (Object) cir.getReturnValue();
if (this.viaFabricPlus$has1_10Tag) {
mixinItemStack.viaFabricPlus$set1_10Count(this.viaFabricPlus$1_10Count);
@Unique
private void viaFabricPlus$appendEnchantments1_14_4(final String name, final NbtCompound nbt, Item.TooltipContext context, final Consumer<Text> tooltip) {
final RegistryWrapper.WrapperLookup registryLookup = context.getRegistryLookup();
final NbtList enchantments = nbt.getList(name, NbtElement.COMPOUND_TYPE);
for (NbtElement element : enchantments) {
final NbtCompound enchantment = (NbtCompound) element;
final String id = enchantment.getString("id");
final Optional<RegistryKey<Enchantment>> value = Enchantments1_14_4.getOrEmpty(id);
value.ifPresent(e -> {
final int lvl = enchantment.getInt("lvl");
if (registryLookup != null) {
final Optional<RegistryEntry.Reference<Enchantment>> v = registryLookup.getWrapperOrThrow(RegistryKeys.ENCHANTMENT).getOptional(e);
v.ifPresent(enchantmentReference -> tooltip.accept(Enchantment.getName(enchantmentReference, MathHelper.clamp(lvl, Short.MIN_VALUE, Short.MAX_VALUE))));
}
});
}
}
@Override
public boolean viaFabricPlus$has1_10Tag() {
return this.viaFabricPlus$has1_10Tag;
}
@Override
public int viaFabricPlus$get1_10Count() {
return this.viaFabricPlus$1_10Count;
}
@Override
public void viaFabricPlus$set1_10Count(final int count) {
this.viaFabricPlus$has1_10Tag = true;
this.viaFabricPlus$1_10Count = count;
}
}

View File

@ -1,100 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import net.minecraft.block.Block;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.item.*;
import net.minecraft.registry.tag.TagKey;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(MiningToolItem.class)
public abstract class MixinMiningToolItem extends ToolItem {
@Shadow
@Final
private float attackDamage;
@Shadow
@Final
private Multimap<EntityAttribute, EntityAttributeModifier> attributeModifiers;
@Unique
private float viaFabricPlus$attackDamage_r1_8;
@Unique
private Multimap<EntityAttribute, EntityAttributeModifier> viaFabricPlus$AttributeModifiers_r1_8;
public MixinMiningToolItem(ToolMaterial material, Settings settings) {
super(material, settings);
}
@Inject(method = "<init>", at = @At("RETURN"))
private void init1_8Fields(float attackDamage, float attackSpeed, ToolMaterial material, TagKey<Block> effectiveBlocks, Settings settings, CallbackInfo ci) {
final float materialAttackDamage = material.getAttackDamage();
if ((Item) this instanceof PickaxeItem) {
this.viaFabricPlus$attackDamage_r1_8 = 2 + materialAttackDamage;
} else if ((Item) this instanceof ShovelItem) {
this.viaFabricPlus$attackDamage_r1_8 = 1 + materialAttackDamage;
} else if ((Item) this instanceof AxeItem) {
this.viaFabricPlus$attackDamage_r1_8 = 3 + materialAttackDamage;
} else { // HoeItem didn't use MiningToolItem abstraction in 1.8
this.viaFabricPlus$AttributeModifiers_r1_8 = ImmutableMultimap.of();
return;
}
final ImmutableMultimap.Builder<EntityAttribute, EntityAttributeModifier> builder = ImmutableMultimap.builder();
builder.put(EntityAttributes.GENERIC_ATTACK_DAMAGE, new EntityAttributeModifier(ATTACK_DAMAGE_MODIFIER_ID, "Tool modifier", this.viaFabricPlus$attackDamage_r1_8, EntityAttributeModifier.Operation.ADDITION));
this.viaFabricPlus$AttributeModifiers_r1_8 = builder.build();
}
@Redirect(method = "getAttackDamage", at = @At(value = "FIELD", target = "Lnet/minecraft/item/MiningToolItem;attackDamage:F"))
private float changeAttackDamage(MiningToolItem instance) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
return this.viaFabricPlus$attackDamage_r1_8;
} else {
return this.attackDamage;
}
}
@Redirect(method = "getAttributeModifiers", at = @At(value = "FIELD", target = "Lnet/minecraft/item/MiningToolItem;attributeModifiers:Lcom/google/common/collect/Multimap;"))
private Multimap<EntityAttribute, EntityAttributeModifier> changeAttributeModifiers(MiningToolItem instance) {
if (DebugSettings.global().replaceAttributeModifiers.isEnabled()) {
return this.viaFabricPlus$AttributeModifiers_r1_8;
} else {
return this.attributeModifiers;
}
}
}

View File

@ -1,91 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import com.google.common.collect.ImmutableSet;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.fixes.data.Material1_19_4;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.fabricmc.yarn.constants.MiningLevels;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.item.MiningToolItem;
import net.minecraft.item.PickaxeItem;
import net.minecraft.item.ToolMaterial;
import net.minecraft.registry.tag.TagKey;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import java.util.Set;
@Mixin(PickaxeItem.class)
public abstract class MixinPickaxeItem extends MiningToolItem {
@Unique
private static final Set<Block> viaFabricPlus$effective_blocks_b1_8_1 = ImmutableSet.of(Blocks.COBBLESTONE, Blocks.SMOOTH_STONE_SLAB, Blocks.SANDSTONE_SLAB, Blocks.PETRIFIED_OAK_SLAB, Blocks.COBBLESTONE_SLAB, Blocks.BRICK_SLAB, Blocks.STONE_BRICK_SLAB, Blocks.STONE, Blocks.SANDSTONE, Blocks.MOSSY_COBBLESTONE, Blocks.IRON_ORE, Blocks.IRON_BLOCK, Blocks.COAL_ORE, Blocks.GOLD_BLOCK, Blocks.GOLD_ORE, Blocks.DIAMOND_ORE, Blocks.DIAMOND_BLOCK, Blocks.ICE, Blocks.NETHERRACK, Blocks.LAPIS_ORE, Blocks.LAPIS_BLOCK);
@Unique
private static final Set<Block> viaFabricPlus$effective_blocks_r1_15_2 = ImmutableSet.of(Blocks.ACTIVATOR_RAIL, Blocks.COAL_ORE, Blocks.COBBLESTONE, Blocks.DETECTOR_RAIL, Blocks.DIAMOND_BLOCK, Blocks.DIAMOND_ORE, Blocks.POWERED_RAIL, Blocks.GOLD_BLOCK, Blocks.GOLD_ORE, Blocks.ICE, Blocks.IRON_BLOCK, Blocks.IRON_ORE, Blocks.LAPIS_BLOCK, Blocks.LAPIS_ORE, Blocks.MOSSY_COBBLESTONE, Blocks.NETHERRACK, Blocks.PACKED_ICE, Blocks.BLUE_ICE, Blocks.RAIL, Blocks.REDSTONE_ORE, Blocks.SANDSTONE, Blocks.CHISELED_SANDSTONE, Blocks.CUT_SANDSTONE, Blocks.CHISELED_RED_SANDSTONE, Blocks.CUT_RED_SANDSTONE, Blocks.RED_SANDSTONE, Blocks.STONE, Blocks.GRANITE, Blocks.POLISHED_GRANITE, Blocks.DIORITE, Blocks.POLISHED_DIORITE, Blocks.ANDESITE, Blocks.POLISHED_ANDESITE, Blocks.STONE_SLAB, Blocks.SMOOTH_STONE_SLAB, Blocks.SANDSTONE_SLAB, Blocks.PETRIFIED_OAK_SLAB, Blocks.COBBLESTONE_SLAB, Blocks.BRICK_SLAB, Blocks.STONE_BRICK_SLAB, Blocks.NETHER_BRICK_SLAB, Blocks.QUARTZ_SLAB, Blocks.RED_SANDSTONE_SLAB, Blocks.PURPUR_SLAB, Blocks.SMOOTH_QUARTZ, Blocks.SMOOTH_RED_SANDSTONE, Blocks.SMOOTH_SANDSTONE, Blocks.SMOOTH_STONE, Blocks.STONE_BUTTON, Blocks.STONE_PRESSURE_PLATE, Blocks.POLISHED_GRANITE_SLAB, Blocks.SMOOTH_RED_SANDSTONE_SLAB, Blocks.MOSSY_STONE_BRICK_SLAB, Blocks.POLISHED_DIORITE_SLAB, Blocks.MOSSY_COBBLESTONE_SLAB, Blocks.END_STONE_BRICK_SLAB, Blocks.SMOOTH_SANDSTONE_SLAB, Blocks.SMOOTH_QUARTZ_SLAB, Blocks.GRANITE_SLAB, Blocks.ANDESITE_SLAB, Blocks.RED_NETHER_BRICK_SLAB, Blocks.POLISHED_ANDESITE_SLAB, Blocks.DIORITE_SLAB, Blocks.SHULKER_BOX, Blocks.BLACK_SHULKER_BOX, Blocks.BLUE_SHULKER_BOX, Blocks.BROWN_SHULKER_BOX, Blocks.CYAN_SHULKER_BOX, Blocks.GRAY_SHULKER_BOX, Blocks.GREEN_SHULKER_BOX, Blocks.LIGHT_BLUE_SHULKER_BOX, Blocks.LIGHT_GRAY_SHULKER_BOX, Blocks.LIME_SHULKER_BOX, Blocks.MAGENTA_SHULKER_BOX, Blocks.ORANGE_SHULKER_BOX, Blocks.PINK_SHULKER_BOX, Blocks.PURPLE_SHULKER_BOX, Blocks.RED_SHULKER_BOX, Blocks.WHITE_SHULKER_BOX, Blocks.YELLOW_SHULKER_BOX);
@Unique
private static final Set<Block> viaFabricPlus$effective_blocks_r1_16_5 = ImmutableSet.of(Blocks.ACTIVATOR_RAIL, Blocks.COAL_ORE, Blocks.COBBLESTONE, Blocks.DETECTOR_RAIL, Blocks.DIAMOND_BLOCK, Blocks.DIAMOND_ORE, Blocks.POWERED_RAIL, Blocks.GOLD_BLOCK, Blocks.GOLD_ORE, Blocks.NETHER_GOLD_ORE, Blocks.ICE, Blocks.IRON_BLOCK, Blocks.IRON_ORE, Blocks.LAPIS_BLOCK, Blocks.LAPIS_ORE, Blocks.MOSSY_COBBLESTONE, Blocks.NETHERRACK, Blocks.PACKED_ICE, Blocks.BLUE_ICE, Blocks.RAIL, Blocks.REDSTONE_ORE, Blocks.SANDSTONE, Blocks.CHISELED_SANDSTONE, Blocks.CUT_SANDSTONE, Blocks.CHISELED_RED_SANDSTONE, Blocks.CUT_RED_SANDSTONE, Blocks.RED_SANDSTONE, Blocks.STONE, Blocks.GRANITE, Blocks.POLISHED_GRANITE, Blocks.DIORITE, Blocks.POLISHED_DIORITE, Blocks.ANDESITE, Blocks.POLISHED_ANDESITE, Blocks.STONE_SLAB, Blocks.SMOOTH_STONE_SLAB, Blocks.SANDSTONE_SLAB, Blocks.PETRIFIED_OAK_SLAB, Blocks.COBBLESTONE_SLAB, Blocks.BRICK_SLAB, Blocks.STONE_BRICK_SLAB, Blocks.NETHER_BRICK_SLAB, Blocks.QUARTZ_SLAB, Blocks.RED_SANDSTONE_SLAB, Blocks.PURPUR_SLAB, Blocks.SMOOTH_QUARTZ, Blocks.SMOOTH_RED_SANDSTONE, Blocks.SMOOTH_SANDSTONE, Blocks.SMOOTH_STONE, Blocks.STONE_BUTTON, Blocks.STONE_PRESSURE_PLATE, Blocks.POLISHED_GRANITE_SLAB, Blocks.SMOOTH_RED_SANDSTONE_SLAB, Blocks.MOSSY_STONE_BRICK_SLAB, Blocks.POLISHED_DIORITE_SLAB, Blocks.MOSSY_COBBLESTONE_SLAB, Blocks.END_STONE_BRICK_SLAB, Blocks.SMOOTH_SANDSTONE_SLAB, Blocks.SMOOTH_QUARTZ_SLAB, Blocks.GRANITE_SLAB, Blocks.ANDESITE_SLAB, Blocks.RED_NETHER_BRICK_SLAB, Blocks.POLISHED_ANDESITE_SLAB, Blocks.DIORITE_SLAB, Blocks.SHULKER_BOX, Blocks.BLACK_SHULKER_BOX, Blocks.BLUE_SHULKER_BOX, Blocks.BROWN_SHULKER_BOX, Blocks.CYAN_SHULKER_BOX, Blocks.GRAY_SHULKER_BOX, Blocks.GREEN_SHULKER_BOX, Blocks.LIGHT_BLUE_SHULKER_BOX, Blocks.LIGHT_GRAY_SHULKER_BOX, Blocks.LIME_SHULKER_BOX, Blocks.MAGENTA_SHULKER_BOX, Blocks.ORANGE_SHULKER_BOX, Blocks.PINK_SHULKER_BOX, Blocks.PURPLE_SHULKER_BOX, Blocks.RED_SHULKER_BOX, Blocks.WHITE_SHULKER_BOX, Blocks.YELLOW_SHULKER_BOX, Blocks.PISTON, Blocks.STICKY_PISTON, Blocks.PISTON_HEAD);
@Unique
private static final Set<Material1_19_4> viaFabricPlus$effective_materials_r1_16_5 = ImmutableSet.of(Material1_19_4.METAL, Material1_19_4.REPAIR_STATION, Material1_19_4.STONE);
protected MixinPickaxeItem(float attackDamage, float attackSpeed, ToolMaterial material, TagKey<Block> effectiveBlocks, Settings settings) {
super(attackDamage, attackSpeed, material, effectiveBlocks, settings);
}
@Override
public boolean isSuitableFor(BlockState state) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_16_4)) {
final int miningLevel = this.getMaterial().getMiningLevel();
if (state.isOf(Blocks.OBSIDIAN) || state.isOf(Blocks.CRYING_OBSIDIAN) || state.isOf(Blocks.NETHERITE_BLOCK) || state.isOf(Blocks.RESPAWN_ANCHOR) || state.isOf(Blocks.ANCIENT_DEBRIS)) {
return miningLevel >= MiningLevels.DIAMOND;
} else if (state.isOf(Blocks.DIAMOND_BLOCK) || state.isOf(Blocks.DIAMOND_ORE) || state.isOf(Blocks.EMERALD_ORE) || state.isOf(Blocks.EMERALD_BLOCK) || state.isOf(Blocks.GOLD_BLOCK) || state.isOf(Blocks.GOLD_ORE) || state.isOf(Blocks.REDSTONE_ORE)) {
return miningLevel >= MiningLevels.IRON;
} else if (state.isOf(Blocks.IRON_BLOCK) || state.isOf(Blocks.IRON_ORE) || state.isOf(Blocks.LAPIS_BLOCK) || state.isOf(Blocks.LAPIS_ORE)) {
return miningLevel >= MiningLevels.STONE;
} else {
return viaFabricPlus$effective_materials_r1_16_5.contains(Material1_19_4.getMaterial(state)) || state.isOf(Blocks.NETHER_GOLD_ORE);
}
} else {
return super.isSuitableFor(state);
}
}
@Override
public float getMiningSpeedMultiplier(ItemStack stack, BlockState state) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) {
return viaFabricPlus$effective_blocks_b1_8_1.contains(state.getBlock()) ? this.miningSpeed : 1.0F;
} else if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_15_2)) {
return viaFabricPlus$effective_materials_r1_16_5.contains(Material1_19_4.getMaterial(state)) ? this.miningSpeed : viaFabricPlus$effective_blocks_r1_15_2.contains(state.getBlock()) ? this.miningSpeed : 1.0F;
} else if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_16_4)) {
return viaFabricPlus$effective_materials_r1_16_5.contains(Material1_19_4.getMaterial(state)) ? this.miningSpeed : viaFabricPlus$effective_blocks_r1_16_5.contains(state.getBlock()) ? this.miningSpeed : 1.0F;
}
return super.getMiningSpeedMultiplier(stack, state);
}
}

View File

@ -1,61 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ShearsItem;
import net.minecraft.registry.tag.BlockTags;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ShearsItem.class)
public abstract class MixinShearsItem extends Item {
public MixinShearsItem(Settings settings) {
super(settings);
}
@Inject(method = "getMiningSpeedMultiplier", at = @At("HEAD"), cancellable = true)
private void changeMiningSpeed(ItemStack stack, BlockState state, CallbackInfoReturnable<Float> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_16_4)) {
if (!state.isOf(Blocks.COBWEB) && !state.isIn(BlockTags.LEAVES)) {
cir.setReturnValue(state.isIn(BlockTags.WOOL) ? 5.0F : super.getMiningSpeedMultiplier(stack, state));
} else {
cir.setReturnValue(15.0F);
}
}
}
@Inject(method = "isSuitableFor", at = @At("HEAD"), cancellable = true)
private void changeEffectiveBlocks(BlockState state, CallbackInfoReturnable<Boolean> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) {
cir.setReturnValue(state.isOf(Blocks.COBWEB));
}
}
}

View File

@ -19,45 +19,18 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import com.google.common.collect.ImmutableSet;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.*;
import net.minecraft.registry.tag.TagKey;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.minecraft.item.ShovelItem;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.Slice;
import java.util.Map;
import java.util.Set;
@Mixin(ShovelItem.class)
public abstract class MixinShovelItem extends MiningToolItem {
@Unique
private static final Set<Block> viaFabricPlus$effective_blocks_b1_8_1 = ImmutableSet.of(Blocks.GRASS_BLOCK, Blocks.DIRT, Blocks.SAND, Blocks.GRAVEL, Blocks.SNOW, Blocks.SNOW_BLOCK, Blocks.CLAY, Blocks.FARMLAND);
@Unique
private static final Set<Block> viaFabricPlus$effective_blocks_r1_16_5 = ImmutableSet.of(Blocks.CLAY, Blocks.DIRT, Blocks.COARSE_DIRT, Blocks.PODZOL, Blocks.FARMLAND, Blocks.GRASS_BLOCK, Blocks.GRAVEL, Blocks.MYCELIUM, Blocks.SAND, Blocks.RED_SAND, Blocks.SNOW_BLOCK, Blocks.SNOW, Blocks.SOUL_SAND, Blocks.DIRT_PATH, Blocks.WHITE_CONCRETE_POWDER, Blocks.ORANGE_CONCRETE_POWDER, Blocks.MAGENTA_CONCRETE_POWDER, Blocks.LIGHT_BLUE_CONCRETE_POWDER, Blocks.YELLOW_CONCRETE_POWDER, Blocks.LIME_CONCRETE_POWDER, Blocks.PINK_CONCRETE_POWDER, Blocks.GRAY_CONCRETE_POWDER, Blocks.LIGHT_GRAY_CONCRETE_POWDER, Blocks.CYAN_CONCRETE_POWDER, Blocks.PURPLE_CONCRETE_POWDER, Blocks.BLUE_CONCRETE_POWDER, Blocks.BROWN_CONCRETE_POWDER, Blocks.GREEN_CONCRETE_POWDER, Blocks.RED_CONCRETE_POWDER, Blocks.BLACK_CONCRETE_POWDER, Blocks.SOUL_SOIL);
protected MixinShovelItem(float attackDamage, float attackSpeed, ToolMaterial material, TagKey<Block> effectiveBlocks, Item.Settings settings) {
super(attackDamage, attackSpeed, material, effectiveBlocks, settings);
}
@Override
public boolean isSuitableFor(BlockState state) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_16_4)) {
return state.isOf(Blocks.SNOW) || state.isOf(Blocks.SNOW_BLOCK);
} else {
return super.isSuitableFor(state);
}
}
public abstract class MixinShovelItem {
@Redirect(method = "useOnBlock", slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/item/ShovelItem;PATH_STATES:Ljava/util/Map;")), at = @At(value = "INVOKE", target = "Ljava/util/Map;get(Ljava/lang/Object;)Ljava/lang/Object;", ordinal = 0, remap = false))
private Object disablePathAction(Map<Object, Object> instance, Object grassBlock) {
@ -68,15 +41,4 @@ public abstract class MixinShovelItem extends MiningToolItem {
}
}
@Override
public float getMiningSpeedMultiplier(ItemStack stack, BlockState state) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) {
return viaFabricPlus$effective_blocks_b1_8_1.contains(state.getBlock()) ? this.miningSpeed : 1.0F;
} else if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_16_4)) {
return viaFabricPlus$effective_blocks_r1_16_5.contains(state.getBlock()) ? this.miningSpeed : 1.0F;
}
return super.getMiningSpeedMultiplier(stack, state);
}
}

View File

@ -19,76 +19,23 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.item;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.attribute.EntityAttribute;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.SwordItem;
import net.minecraft.item.ToolItem;
import net.minecraft.item.ToolMaterial;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
import net.minecraft.util.UseAction;
import net.minecraft.world.World;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(SwordItem.class)
public abstract class MixinSwordItem extends ToolItem {
@Shadow
@Final
private float attackDamage;
@Shadow
@Final
private Multimap<EntityAttribute, EntityAttributeModifier> attributeModifiers;
@Unique
private float viaFabricPlus$attackDamage_r1_8;
@Unique
private Multimap<EntityAttribute, EntityAttributeModifier> viaFabricPlus$AttributeModifiers_r1_8;
public MixinSwordItem(ToolMaterial material, Settings settings) {
super(material, settings);
}
@Inject(method = "<init>", at = @At("RETURN"))
private void init1_8Fields(ToolMaterial toolMaterial, int attackDamage, float attackSpeed, Settings settings, CallbackInfo ci) {
this.viaFabricPlus$attackDamage_r1_8 = 4 + toolMaterial.getAttackDamage();
final ImmutableMultimap.Builder<EntityAttribute, EntityAttributeModifier> builder = ImmutableMultimap.builder();
builder.put(EntityAttributes.GENERIC_ATTACK_DAMAGE, new EntityAttributeModifier(ATTACK_DAMAGE_MODIFIER_ID, "Weapon modifier", this.viaFabricPlus$attackDamage_r1_8, EntityAttributeModifier.Operation.ADDITION));
this.viaFabricPlus$AttributeModifiers_r1_8 = builder.build();
}
@Override
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
if (ProtocolTranslator.getTargetVersion().betweenInclusive(LegacyProtocolVersion.b1_8tob1_8_1, ProtocolVersion.v1_8)) {
ItemStack itemStack = user.getStackInHand(hand);
user.setCurrentHand(hand);
return TypedActionResult.consume(itemStack);
} else {
return super.use(world, user, hand);
}
}
@Override
public UseAction getUseAction(ItemStack stack) {
if (ProtocolTranslator.getTargetVersion().betweenInclusive(LegacyProtocolVersion.b1_8tob1_8_1, ProtocolVersion.v1_8)) {
@ -98,38 +45,4 @@ public abstract class MixinSwordItem extends ToolItem {
}
}
@Override
public int getMaxUseTime(ItemStack stack) {
if (ProtocolTranslator.getTargetVersion().betweenInclusive(LegacyProtocolVersion.b1_8tob1_8_1, ProtocolVersion.v1_8)) {
return 72000;
} else {
return super.getMaxUseTime(stack);
}
}
@Redirect(method = "getAttackDamage", at = @At(value = "FIELD", target = "Lnet/minecraft/item/SwordItem;attackDamage:F"))
private float changeAttackDamage(SwordItem instance) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
return this.viaFabricPlus$attackDamage_r1_8;
} else {
return this.attackDamage;
}
}
@Redirect(method = "getAttributeModifiers", at = @At(value = "FIELD", target = "Lnet/minecraft/item/SwordItem;attributeModifiers:Lcom/google/common/collect/Multimap;"))
private Multimap<EntityAttribute, EntityAttributeModifier> changeAttributeModifiers(SwordItem instance) {
if (DebugSettings.global().replaceAttributeModifiers.isEnabled()) {
return this.viaFabricPlus$AttributeModifiers_r1_8;
} else {
return this.attributeModifiers;
}
}
@Inject(method = "getMiningSpeedMultiplier", at = @At("HEAD"), cancellable = true)
private void changeMiningSpeed(ItemStack stack, BlockState state, CallbackInfoReturnable<Float> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(LegacyProtocolVersion.b1_8tob1_8_1)) {
cir.setReturnValue(state.isOf(Blocks.COBWEB) ? 15.0F : 1.5F);
}
}
}

View File

@ -20,12 +20,11 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.network;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.storage.InventoryAcknowledgements;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.storage.InventoryAcknowledgements;
import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import de.florianmichael.viafabricplus.injection.access.IClientConnection;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.fabricmc.fabric.impl.networking.payload.ResolvablePayload;
import net.fabricmc.fabric.impl.networking.payload.UntypedPayload;
import de.florianmichael.viafabricplus.util.DataCustomPayload;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientCommonNetworkHandler;
import net.minecraft.network.ClientConnection;
@ -49,7 +48,6 @@ import java.net.URL;
import java.time.Duration;
import java.util.function.BooleanSupplier;
@SuppressWarnings("UnstableApiUsage")
@Mixin(value = ClientCommonNetworkHandler.class, priority = 1 /* Has to be applied before Fabric's Networking API, so it doesn't cancel our custom-payload packets */)
public abstract class MixinClientCommonNetworkHandler {
@ -73,6 +71,16 @@ public abstract class MixinClientCommonNetworkHandler {
return null;
}
@Inject(method = "onResourcePackSend", at = @At("HEAD"), cancellable = true)
private void validateUrlInNetworkThread(ResourcePackSendS2CPacket packet, CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_2)) {
if (getParsedResourcePackUrl(packet.url()) == null) {
this.connection.send(new ResourcePackStatusC2SPacket(packet.id(), ResourcePackStatusC2SPacket.Status.INVALID_URL));
ci.cancel();
}
}
}
@Redirect(method = "onKeepAlive", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientCommonNetworkHandler;send(Lnet/minecraft/network/packet/Packet;Ljava/util/function/BooleanSupplier;Ljava/time/Duration;)V"))
private void forceSendKeepAlive(ClientCommonNetworkHandler instance, Packet<? extends ServerPacketListener> packet, BooleanSupplier sendCondition, Duration expiry) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_19_3)) {
@ -104,20 +112,10 @@ public abstract class MixinClientCommonNetworkHandler {
@Inject(method = "onCustomPayload(Lnet/minecraft/network/packet/s2c/common/CustomPayloadS2CPacket;)V", at = @At("HEAD"), cancellable = true)
private void handleSyncTask(CustomPayloadS2CPacket packet, CallbackInfo ci) {
if (packet.payload().id().toString().equals(ClientsideFixes.PACKET_SYNC_IDENTIFIER) && packet.payload() instanceof ResolvablePayload payload) {
ClientsideFixes.handleSyncTask(((UntypedPayload) payload.resolve(null)).buffer());
if (packet.payload() instanceof DataCustomPayload dataCustomPayload) {
ClientsideFixes.handleSyncTask(dataCustomPayload.buf());
ci.cancel(); // Cancel the packet, so it doesn't get processed by the client
}
}
@Inject(method = "onResourcePackSend", at = @At("HEAD"), cancellable = true)
private void validateUrlInNetworkThread(ResourcePackSendS2CPacket packet, CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_2)) {
if (getParsedResourcePackUrl(packet.url()) == null) {
this.connection.send(new ResourcePackStatusC2SPacket(packet.id(), ResourcePackStatusC2SPacket.Status.INVALID_URL));
ci.cancel();
}
}
}
}

View File

@ -22,8 +22,13 @@ package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.network;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.util.ChatUtil;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientCommonNetworkHandler;
import net.minecraft.client.network.ClientConfigurationNetworkHandler;
import net.minecraft.client.network.ClientConnectionState;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.packet.s2c.config.FeaturesS2CPacket;
import net.minecraft.network.packet.s2c.config.ReadyS2CPacket;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
@ -33,11 +38,29 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientConfigurationNetworkHandler.class)
public abstract class MixinClientConfigurationNetworkHandler {
public abstract class MixinClientConfigurationNetworkHandler extends ClientCommonNetworkHandler {
protected MixinClientConfigurationNetworkHandler(MinecraftClient client, ClientConnection connection, ClientConnectionState connectionState) {
super(client, connection, connectionState);
}
@Inject(method = "onReady", at = @At("HEAD"))
private void disableAutoRead(ReadyS2CPacket packet, CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_3)) {
this.connection.channel.config().setAutoRead(false);
}
}
@Inject(method = "onReady", at = @At("RETURN"))
private void enableAutoRead(ReadyS2CPacket packet, CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_3)) {
this.connection.channel.config().setAutoRead(true);
}
}
@Inject(method = "onFeatures", at = @At(value = "HEAD"))
private void notifyAboutFeatures(FeaturesS2CPacket packet, CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThan(ProtocolVersion.v1_20) && packet.features().contains(new Identifier("update_1_20"))) {
if (ProtocolTranslator.getTargetVersion().olderThan(ProtocolVersion.v1_20) && packet.features().contains(Identifier.of("update_1_20"))) {
ChatUtil.sendPrefixedMessage(Text.literal("This server has the update_1_20 features enabled. This is not fully supported and may cause issues.").formatted(Formatting.RED));
}
}

View File

@ -22,18 +22,27 @@ package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.network;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.sugar.Local;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import de.florianmichael.viafabricplus.fixes.data.recipe.RecipeInfo;
import de.florianmichael.viafabricplus.fixes.data.recipe.Recipes1_11_2;
import de.florianmichael.viafabricplus.injection.access.IDownloadingTerrainScreen;
import de.florianmichael.viafabricplus.injection.access.IPlayerListHud;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.DownloadingTerrainScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.BookScreen;
import net.minecraft.client.network.*;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.entity.attribute.AttributeContainer;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.packet.c2s.play.ClientStatusC2SPacket;
import net.minecraft.network.packet.s2c.play.*;
import net.minecraft.recipe.RecipeEntry;
import net.minecraft.registry.RegistryKey;
@ -57,9 +66,6 @@ import java.util.Set;
@Mixin(ClientPlayNetworkHandler.class)
public abstract class MixinClientPlayNetworkHandler extends ClientCommonNetworkHandler {
@Shadow
public abstract void onEntityStatus(EntityStatusS2CPacket packet);
@Mutable
@Shadow
@Final
@ -81,8 +87,64 @@ public abstract class MixinClientPlayNetworkHandler extends ClientCommonNetworkH
super(client, connection, connectionState);
}
@WrapWithCondition(method = "onPlayerRespawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;startWorldLoading(Lnet/minecraft/client/network/ClientPlayerEntity;Lnet/minecraft/client/world/ClientWorld;)V"))
private boolean checkDimensionChange(ClientPlayNetworkHandler instance, ClientPlayerEntity player, ClientWorld world, @Local RegistryKey<World> registryKey) {
@WrapWithCondition(method = "onPlayerRespawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/attribute/AttributeContainer;setBaseFrom(Lnet/minecraft/entity/attribute/AttributeContainer;)V"))
private boolean dontApplyBaseValues(AttributeContainer instance, AttributeContainer other) {
return ProtocolTranslator.getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_21);
}
@Redirect(method = "onGameStateChange", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;setScreen(Lnet/minecraft/client/gui/screen/Screen;)V", ordinal = 0))
private void handleWinGameState0(MinecraftClient instance, Screen screen, @Local int i) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_5)) {
if (i == 0) {
this.client.player.networkHandler.sendPacket(new ClientStatusC2SPacket(ClientStatusC2SPacket.Mode.PERFORM_RESPAWN));
this.client.setScreen(new DownloadingTerrainScreen(() -> false, DownloadingTerrainScreen.WorldEntryReason.END_PORTAL));
} else if (i == 1) {
instance.setScreen(screen);
}
} else {
instance.setScreen(screen);
}
}
@WrapWithCondition(method = "onEnterReconfiguration", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendAcknowledgment()V"))
private boolean dontSendChatAck(ClientPlayNetworkHandler instance) {
return ProtocolTranslator.getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_20_5);
}
@Redirect(method = "onOpenWrittenBook", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/ingame/BookScreen$Contents;create(Lnet/minecraft/item/ItemStack;)Lnet/minecraft/client/gui/screen/ingame/BookScreen$Contents;"))
private BookScreen.Contents dontOpenWriteableBookScreen(ItemStack stack) {
if (ProtocolTranslator.getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_20_5) || stack.isOf(Items.WRITTEN_BOOK)) {
return BookScreen.Contents.create(stack);
} else {
return null;
}
}
@Inject(method = "onEnterReconfiguration", at = @At("HEAD"))
private void disableAutoRead(EnterReconfigurationS2CPacket packet, CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_3)) {
this.connection.channel.config().setAutoRead(false);
}
}
@Inject(method = "onEnterReconfiguration", at = @At("RETURN"))
private void enableAutoRead(EnterReconfigurationS2CPacket packet, CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_3)) {
this.connection.channel.config().setAutoRead(true);
}
}
@Redirect(method = "sendChatCommand", at = @At(value = "INVOKE", target = "Ljava/util/List;isEmpty()Z"))
private boolean alwaysSignCommands(List<?> instance) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20_3)) {
return false;
} else {
return instance.isEmpty();
}
}
@WrapWithCondition(method = "onPlayerRespawn", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;startWorldLoading(Lnet/minecraft/client/network/ClientPlayerEntity;Lnet/minecraft/client/world/ClientWorld;Lnet/minecraft/client/gui/screen/DownloadingTerrainScreen$WorldEntryReason;)V"))
private boolean checkDimensionChange(ClientPlayNetworkHandler instance, ClientPlayerEntity player, ClientWorld world, DownloadingTerrainScreen.WorldEntryReason worldEntryReason, @Local(ordinal = 0) RegistryKey<World> registryKey) {
return ProtocolTranslator.getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_20_3) || registryKey != this.client.player.getWorld().getRegistryKey();
}
@ -124,7 +186,7 @@ public abstract class MixinClientPlayNetworkHandler extends ClientCommonNetworkH
}
}
@Redirect(method = "onServerMetadata", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;isSecureChatEnforced()Z"))
@Redirect(method = "onGameJoin", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;isSecureChatEnforced()Z"))
private boolean removeSecureChatWarning(ClientPlayNetworkHandler instance) {
return isSecureChatEnforced() || VisualSettings.global().disableSecureChatWarning.isEnabled();
}
@ -170,19 +232,17 @@ public abstract class MixinClientPlayNetworkHandler extends ClientCommonNetworkH
}
@Inject(method = "onGameJoin", at = @At("RETURN"))
private void sendAdditionalData(CallbackInfo ci) {
private void sendRecipes(GameJoinS2CPacket packet, CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_11_1)) {
final List<RecipeEntry<?>> recipes = new ArrayList<>();
final List<RecipeInfo> recipeInfos = Recipes1_11_2.getRecipes(ProtocolTranslator.getTargetVersion());
for (int i = 0; i < recipeInfos.size(); i++) {
recipes.add(recipeInfos.get(i).create(new Identifier("viafabricplus", "recipe/" + i)));
recipes.add(recipeInfos.get(i).create(Identifier.of("viafabricplus", "recipe/" + i)));
}
this.onSynchronizeRecipes(new SynchronizeRecipesS2CPacket(recipes));
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
this.onEntityStatus(new EntityStatusS2CPacket(this.client.player, (byte) 28)); // Op-level 4
}
}
ClientsideFixes.GLOBAL_TABLIST_INDEX = 0;
((IPlayerListHud) MinecraftClient.getInstance().inGameHud.getPlayerListHud()).viaFabricPlus$setMaxPlayers(packet.maxPlayers());
}
}

View File

@ -23,9 +23,9 @@ import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.llamalad7.mixinextras.sugar.Local;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_16_2to1_16_1.ServerboundPackets1_16_2;
import com.viaversion.viaversion.protocols.protocol1_17to1_16_4.Protocol1_17To1_16_4;
import com.viaversion.viaversion.api.type.Types;
import com.viaversion.viaversion.protocols.v1_16_1to1_16_2.packet.ServerboundPackets1_16_2;
import com.viaversion.viaversion.protocols.v1_16_4to1_17.Protocol1_16_4To1_17;
import de.florianmichael.viafabricplus.fixes.versioned.ActionResultException1_12_2;
import de.florianmichael.viafabricplus.fixes.versioned.ClientPlayerInteractionManager1_18_2;
import de.florianmichael.viafabricplus.injection.access.IClientConnection;
@ -53,6 +53,7 @@ import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
@ -108,6 +109,13 @@ public abstract class MixinClientPlayerInteractionManager implements IClientPlay
@Unique
private final ClientPlayerInteractionManager1_18_2 viaFabricPlus$1_18_2InteractionManager = new ClientPlayerInteractionManager1_18_2();
@Inject(method = "interactItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;syncSelectedSlot()V", shift = At.Shift.AFTER))
private void sendPlayerPosPacket(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResult> cir) {
if (ProtocolTranslator.getTargetVersion().betweenInclusive(ProtocolVersion.v1_17, ProtocolVersion.v1_20_5)) {
this.networkHandler.sendPacket(new PlayerMoveC2SPacket.Full(player.getX(), player.getY(), player.getZ(), player.getYaw(), player.getPitch(), player.isOnGround()));
}
}
@Inject(method = "getBlockBreakingProgress", at = @At("HEAD"), cancellable = true)
private void changeCalculation(CallbackInfoReturnable<Integer> cir) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_19_4)) {
@ -130,11 +138,6 @@ public abstract class MixinClientPlayerInteractionManager implements IClientPlay
return new PlayerActionC2SPacket(action, pos, direction);
}
@WrapWithCondition(method = "interactItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;)V", ordinal = 0))
private boolean redirectPlayerPosPacket(ClientPlayNetworkHandler instance, Packet<?> packet) {
return ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_16_4);
}
@ModifyVariable(method = "clickSlot", at = @At(value = "STORE"), ordinal = 0)
private List<ItemStack> captureOldItems(List<ItemStack> oldItems) {
viaFabricPlus$oldCursorStack = client.player.currentScreenHandler.getCursorStack().copy();
@ -142,7 +145,7 @@ public abstract class MixinClientPlayerInteractionManager implements IClientPlay
}
@WrapWithCondition(method = "clickSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/packet/Packet;)V"))
private boolean handleWindowClick1_16_5(ClientPlayNetworkHandler instance, Packet<?> packet) throws Exception {
private boolean handleWindowClick1_16_5(ClientPlayNetworkHandler instance, Packet<?> packet) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_16_4) && packet instanceof ClickSlotC2SPacket clickSlot) {
ItemStack slotItemBeforeModification;
if (this.viaFabricPlus$shouldBeEmpty(clickSlot.getActionType(), clickSlot.getSlot())) {
@ -153,14 +156,14 @@ public abstract class MixinClientPlayerInteractionManager implements IClientPlay
slotItemBeforeModification = viaFabricPlus$oldItems.get(clickSlot.getSlot());
}
final PacketWrapper clickWindowPacket = PacketWrapper.create(ServerboundPackets1_16_2.CLICK_WINDOW, ((IClientConnection) networkHandler.getConnection()).viaFabricPlus$getUserConnection());
clickWindowPacket.write(Type.UNSIGNED_BYTE, (short) clickSlot.getSyncId());
clickWindowPacket.write(Type.SHORT, (short) clickSlot.getSlot());
clickWindowPacket.write(Type.BYTE, (byte) clickSlot.getButton());
clickWindowPacket.write(Type.SHORT, ((IScreenHandler) client.player.currentScreenHandler).viaFabricPlus$incrementAndGetActionId());
clickWindowPacket.write(Type.VAR_INT, clickSlot.getActionType().ordinal());
clickWindowPacket.write(Type.ITEM1_13_2, ItemTranslator.mcToVia(slotItemBeforeModification, ProtocolVersion.v1_16_4));
clickWindowPacket.scheduleSendToServer(Protocol1_17To1_16_4.class);
final PacketWrapper containerClick = PacketWrapper.create(ServerboundPackets1_16_2.CONTAINER_CLICK, ((IClientConnection) networkHandler.getConnection()).viaFabricPlus$getUserConnection());
containerClick.write(Types.UNSIGNED_BYTE, (short) clickSlot.getSyncId());
containerClick.write(Types.SHORT, (short) clickSlot.getSlot());
containerClick.write(Types.BYTE, (byte) clickSlot.getButton());
containerClick.write(Types.SHORT, ((IScreenHandler) client.player.currentScreenHandler).viaFabricPlus$incrementAndGetActionId());
containerClick.write(Types.VAR_INT, clickSlot.getActionType().ordinal());
containerClick.write(Types.ITEM1_13_2, ItemTranslator.mcToVia(slotItemBeforeModification, ProtocolVersion.v1_16_4));
containerClick.scheduleSendToServer(Protocol1_16_4To1_17.class);
viaFabricPlus$oldCursorStack = null;
viaFabricPlus$oldItems = null;
@ -171,7 +174,7 @@ public abstract class MixinClientPlayerInteractionManager implements IClientPlay
}
@Redirect(method = {"method_41936", "method_41935"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;breakBlock(Lnet/minecraft/util/math/BlockPos;)Z"))
private boolean checkFireBlock(ClientPlayerInteractionManager instance, BlockPos pos, @Local Direction direction) {
private boolean checkFireBlock(ClientPlayerInteractionManager instance, BlockPos pos, @Local(argsOnly = true) Direction direction) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_15_2)) {
return !this.viaFabricPlus$extinguishFire(pos, direction) && instance.breakBlock(pos);
} else {

View File

@ -1,88 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.network;
import com.google.common.collect.ImmutableMap;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.BrandCustomPayload;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket;
import net.minecraft.network.packet.s2c.custom.DebugGameTestAddMarkerCustomPayload;
import net.minecraft.network.packet.s2c.custom.DebugGameTestClearCustomPayload;
import net.minecraft.util.Identifier;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.Map;
@Mixin(CustomPayloadS2CPacket.class)
public abstract class MixinCustomPayloadS2CPacket {
@Unique
private static final Map<Identifier, ProtocolVersion> viaFabricPlus$PAYLOAD_DIFF = ImmutableMap.<Identifier, ProtocolVersion>builder()
.put(BrandCustomPayload.ID, LegacyProtocolVersion.c0_0_15a_1)
.put(DebugGameTestAddMarkerCustomPayload.ID, ProtocolVersion.v1_14)
.put(DebugGameTestClearCustomPayload.ID, ProtocolVersion.v1_14)
.build();
@Redirect(method = "readPayload", at = @At(value = "INVOKE", target = "Ljava/util/Map;get(Ljava/lang/Object;)Ljava/lang/Object;", remap = false))
private static Object filterAllowedCustomPayloads(Map<Identifier, PacketByteBuf.PacketReader<? extends CustomPayload>> instance, Object object) {
final Identifier identifier = (Identifier) object;
if (instance.containsKey(identifier)) {
final PacketByteBuf.PacketReader<? extends CustomPayload> reader = instance.get(identifier);
// 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.
if (!identifier.getNamespace().equals(Identifier.DEFAULT_NAMESPACE)) {
return reader;
}
// Technically it's wrong to just drop all payloads, but 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 doesn't do anything on the client anyway.
if (!viaFabricPlus$PAYLOAD_DIFF.containsKey(identifier) || ProtocolTranslator.getTargetVersion().olderThan(viaFabricPlus$PAYLOAD_DIFF.get(identifier))) {
return null;
}
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_20)) {
// Skip remaining bytes after reading the payload and return null if the payload fails to read
return (PacketByteBuf.PacketReader<? extends CustomPayload>) packetByteBuf -> {
try {
final CustomPayload result = reader.apply(packetByteBuf);
packetByteBuf.skipBytes(packetByteBuf.readableBytes());
return result;
} catch (Exception e) {
return null;
}
};
} else {
return reader;
}
} else {
return null;
}
}
}

View File

@ -17,34 +17,22 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft;
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.network;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.enchantment.EnchantmentHelper;
import io.netty.channel.ChannelConfig;
import net.minecraft.network.handler.NetworkStateTransitionHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(EnchantmentHelper.class)
public abstract class MixinEnchantmentHelper {
@Mixin(NetworkStateTransitionHandler.class)
public interface MixinNetworkStateTransitionHandler {
@ModifyConstant(method = "getLevelFromNbt", constant = @Constant(intValue = 0))
private static int usePossibleMinLevel(int constant) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_14_4)) {
return Short.MIN_VALUE;
} else {
return constant;
}
}
@ModifyConstant(method = "getLevelFromNbt", constant = @Constant(intValue = 255))
private static int usePossibleMaxLevel(int constant) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_14_4)) {
return Short.MAX_VALUE;
} else {
return constant;
}
@WrapWithCondition(method = "onDecoded", at = @At(value = "INVOKE", target = "Lio/netty/channel/ChannelConfig;setAutoRead(Z)Lio/netty/channel/ChannelConfig;", remap = false))
private static boolean dontChangeAutoRead(ChannelConfig instance, boolean b) {
return ProtocolTranslator.getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_20_5);
}
}

View File

@ -0,0 +1,38 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.network;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import io.netty.channel.ChannelConfig;
import net.minecraft.network.handler.NetworkStateTransitions;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@Mixin(NetworkStateTransitions.class)
public abstract class MixinNetworkStateTransitions {
@WrapWithCondition(method = "method_56353", at = @At(value = "INVOKE", target = "Lio/netty/channel/ChannelConfig;setAutoRead(Z)Lio/netty/channel/ChannelConfig;", remap = false))
private static boolean dontChangeAutoRead(ChannelConfig instance, boolean b) {
return ProtocolTranslator.getTargetVersion().newerThanOrEqualTo(ProtocolVersion.v1_20_5);
}
}

View File

@ -1,62 +0,0 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.network;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import de.florianmichael.viafabricplus.injection.access.IItemStack;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.network.PacketByteBuf;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(value = PacketByteBuf.class)
public abstract class MixinPacketByteBuf {
@Redirect(method = "readItemStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;setNbt(Lnet/minecraft/nbt/NbtCompound;)V"))
private void removeViaFabricPlusTag(ItemStack instance, NbtCompound tag) {
if (tag != null && tag.contains(ClientsideFixes.ITEM_COUNT_NBT_TAG, NbtElement.BYTE_TYPE) && ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_10)) {
final IItemStack mixinItemStack = ((IItemStack) (Object) instance);
mixinItemStack.viaFabricPlus$set1_10Count(tag.getByte(ClientsideFixes.ITEM_COUNT_NBT_TAG));
tag.remove(ClientsideFixes.ITEM_COUNT_NBT_TAG);
if (tag.isEmpty()) tag = null;
}
instance.setNbt(tag);
}
@Redirect(method = "writeItemStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;getNbt()Lnet/minecraft/nbt/NbtCompound;"))
private NbtCompound addViaFabricPlusTag(ItemStack instance) {
NbtCompound tag = instance.getNbt();
final IItemStack mixinItemStack = ((IItemStack) (Object) instance);
if (mixinItemStack.viaFabricPlus$has1_10Tag()) {
if (tag == null) tag = new NbtCompound();
tag.putByte(ClientsideFixes.ITEM_COUNT_NBT_TAG, (byte) mixinItemStack.viaFabricPlus$get1_10Count());
}
return tag;
}
}

View File

@ -0,0 +1,38 @@
/*
* This file is part of ViaFabricPlus - https://github.com/FlorianMichael/ViaFabricPlus
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and RK_01/RaphiMC
* Copyright (C) 2023-2024 contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.network;
import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import de.florianmichael.viafabricplus.injection.access.IPlayerListEntry;
import net.minecraft.client.network.PlayerListEntry;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@Mixin(PlayerListEntry.class)
public abstract class MixinPlayerListEntry implements IPlayerListEntry {
@Unique
private final int viaFabricPlus$index = ClientsideFixes.GLOBAL_TABLIST_INDEX++;
@Override
public int viaFabricPlus$getIndex() {
return viaFabricPlus$index;
}
}

View File

@ -20,9 +20,8 @@
package de.florianmichael.viafabricplus.injection.mixin.fixes.minecraft.screen;
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viafabricplus.fixes.ClientsideFixes;
import de.florianmichael.viafabricplus.protocoltranslator.ProtocolTranslator;
import de.florianmichael.viafabricplus.settings.impl.DebugSettings;
import de.florianmichael.viafabricplus.settings.impl.VisualSettings;
import net.minecraft.client.gui.hud.ChatHud;
import net.minecraft.client.gui.hud.MessageIndicator;
@ -65,12 +64,12 @@ public abstract class MixinChatScreen {
@WrapWithCondition(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/TextFieldWidget;setText(Ljava/lang/String;)V"))
public boolean moveSetTextDown(TextFieldWidget instance, String text) {
return ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_12_2);
return !DebugSettings.global().legacyTabCompletions.isEnabled();
}
@Inject(method = "init", at = @At("RETURN"))
private void moveSetTextDown(CallbackInfo ci) {
if (ProtocolTranslator.getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_12_2)) {
if (DebugSettings.global().legacyTabCompletions.isEnabled()) {
this.chatField.setText(this.originalChatText);
this.chatInputSuggestor.refresh();
}
@ -92,7 +91,7 @@ public abstract class MixinChatScreen {
@Unique
private boolean viaFabricPlus$keepTabComplete() {
return ProtocolTranslator.getTargetVersion().newerThan(ProtocolVersion.v1_12_2) || !this.chatField.getText().startsWith("/");
return !DebugSettings.global().legacyTabCompletions.isEnabled() || !this.chatField.getText().startsWith("/");
}
}

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