Compare commits

...

117 Commits

Author SHA1 Message Date
FlorianMichael
42df9d38a4
Bump version to 3.7.1-SNAPSHOT 2024-06-19 20:05:26 +02:00
FlorianMichael
78352cae5b
Release 3.7.0 2024-06-19 19:56:46 +02:00
FlorianMichael
d4d2b8b0ec
Update Via* libraries 2024-06-19 18:08:59 +02:00
FlorianMichael
ad1f3d0c75
Fixup README 2024-06-05 06:43:34 +02:00
FlorianMichael
a26894eba8
Downgrade shadowJar instead of libraries 2024-06-05 06:40:00 +02:00
FlorianMichael
af2102f097
Add toolchain resolving plugin 2024-06-05 04:10:24 +02:00
FlorianMichael
661402cd03
Update GH workflow to J17 again 2024-06-05 03:57:36 +02:00
FlorianMichael
304c021319
Try to finish things up 2024-06-05 03:53:57 +02:00
FlorianMichael
730df46e47
Break Gradle to not check for Java versions 2024-06-04 20:08:53 +02:00
FlorianMichael
eb7c177f3a
Downgrade Via dependencies to J8 2024-06-04 01:33:43 +02:00
FlorianMichael
d7f7fa0bce
Port sources to upstream changes 2024-06-03 20:58:55 +02:00
FlorianMichael
837d29861a
Gradle 8.8 2024-06-03 20:45:48 +02:00
Howard ZHY
4d01ae9eee
Cleanup 1.12 mod metadata (#90)
acceptableRemoteVersions = "*", clientSideOnly=true

Remove spam debug msg
2024-05-06 16:58:50 +02:00
EnZaXD
e9e1aa0e4e
Update Via* 2024-05-05 17:44:51 +02:00
FlorianMichael
f3da973db7
Bump Via* libs to snapshots 2024-04-30 21:42:16 +02:00
FlorianMichael
5e27fb3442
Bump version to 3.6.1-SNAPSHOT 2024-04-30 21:40:08 +02:00
FlorianMichael
ed679a0267
Release 3.6.0 2024-04-30 20:59:25 +02:00
FlorianMichael
d30417a737
[ci skip] Update CHANGELOG 2024-04-30 20:45:42 +02:00
FlorianMichael
9f1a2e2baf
Restructure connecting code and mixins 2024-04-30 20:42:50 +02:00
FlorianMichael
d325b0691d
Fix and clean 1.20.4 platform 2024-04-28 23:42:51 +02:00
FlorianMichael
f589b3a28d
Fix pipeline injection in 1.17+ 2024-04-28 22:57:52 +02:00
FlorianMichael
d2d5ed4458
Don't hook VV into pipeline if target == native ver 2024-04-28 22:38:17 +02:00
Howard ZHY
325494824c
[ci skip] Update README.md (#87) 2024-04-28 22:36:23 +02:00
FlorianMichael
2548bfa8dd
Fix protocol selection in 1.20.4 not working 2024-04-28 22:24:16 +02:00
FlorianMichael
9ba5f28ebd
Rename mixin references as well 2024-04-28 22:15:05 +02:00
FlorianMichael
d93c875d88
Repackage submodules to their explicit game versions 2024-04-28 22:09:11 +02:00
FlorianMichael
2721955931
Add mod publish plugin 2024-04-28 21:30:43 +02:00
FlorianMichael
08cf5e9929
Move mcmod.info into mc 1.12 module, fix artifact names 2024-04-28 21:10:10 +02:00
FlorianMichael
cb49b6d819
Merge remote-tracking branch 'origin/master' 2024-04-28 18:54:48 +02:00
FlorianMichael
d19e57a98e
Beautify version comparisons 2024-04-28 18:54:38 +02:00
FlorianMichael
1f047f0a84
Update Via*, only include common modules 2024-04-28 18:53:39 +02:00
ccetl
3a7053fa0c
Moved the ViaForgeCommon#init call into an FMLCommonSetupEvent listener (#83)
* Moved the ViaForgeCommon#init call into an FMLCommonSetupEvent listener

* Renamed onPostInit to onInit

* Import clean up
2024-03-12 17:35:16 +01:00
FlorianMichael
8657507cca
Removed not working temp migration code 2024-03-11 13:19:10 +01:00
FlorianMichael
53d81b4bdb
Renamed protocolhack -> protocoltranslator 2024-03-11 13:07:58 +01:00
FlorianMichael
fbe5cf8ded
24w09a, port to upstream changes 2024-03-11 13:06:23 +01:00
FlorianMichael
25f3c470e3
[ci skip] Create FUNDING.yml 2024-03-05 13:32:44 +01:00
FlorianMichael
10547649ad
Fixed GUI rendering 2024-02-14 23:18:56 +01:00
FlorianMichael
25af1896f5
24w07a, port to upstream changes (maybe) 2024-02-14 22:47:38 +01:00
EnZaXD
d551e52083
24w06a 2024-02-07 20:00:13 +01:00
FlorianMichael
98c299886f
Next try lol 2024-02-04 01:53:50 +01:00
FlorianMichael
bd7b535134
Gradle 8.5 2024-02-04 01:03:06 +01:00
FlorianMichael
9912150b16
Try java 17 2024-02-04 00:51:48 +01:00
FlorianMichael
060d4b527b
Cleaned build script by using mc_version for comparisons 2024-02-04 00:46:45 +01:00
FlorianMichael
bc32c47617
Removed outdated comments 2024-02-04 00:34:38 +01:00
EnZaXD
b6057fe811
Merge pull request #80 from HowardZHY/master
Update versions in readme
2024-02-03 20:22:34 +01:00
Howard ZHY
fd77239068 Update versions in readme 2024-02-04 03:19:01 +08:00
EnZaXD
45d10be95d
24w05b 2024-02-02 11:30:55 +01:00
EnZaXD
36d14d5554
24w04a 2024-01-26 13:56:21 +01:00
EnZaXD
9d02580e50
24w03b 2024-01-22 19:47:13 +01:00
FlorianMichael
17218b808c
Updated mods.toml files 2024-01-02 17:37:47 +01:00
FlorianMichael
11e365b36d
Update to Minecraft 1.20.4 and Gradle 8.1 2024-01-02 17:19:19 +01:00
FlorianMichael
d0d46e9e6d
Updated Via* 2024-01-02 17:02:53 +01:00
FlorianMichael
cd293c781f
Fixed compile errors 2024-01-02 17:01:21 +01:00
FlorianMichael
4da0b63c19
Updated copyright files 2024-01-01 16:52:20 +01:00
FlorianMichael
80594682a8
2024 2024-01-01 00:56:16 +01:00
FlorianMichael
b91a408d36
Improved mods.toml files 2023-12-08 16:24:17 +01:00
FlorianMichael
c202c4c3ca
Removed debug print 2023-12-08 15:40:48 +01:00
FlorianMichael
758dc93bc7
Update Via* libraries 2023-12-06 22:11:18 +01:00
FlorianMichael
2bd493a166
Rework build structure to prevent gradle plugins
Drop 1.14/1.15 as Forge doesn't seem to like Mixins on those versions
Fixed 1.17+ GUI rendering crashing for OpenGL exceptions
2023-12-06 22:05:18 +01:00
FlorianMichael
c9efed6697
Bump version to 3.6.0-SNAPSHOT 2023-12-06 22:04:45 +01:00
FlorianMichael
76ec05ec35
Release 3.5.0 2023-12-05 20:02:15 +01:00
FlorianMichael
79631f7caf
Some final cleanup before 1.20.3 2023-12-02 01:14:12 +01:00
EnZaXD
a6c9ed237f
1.20.3-rc1 2023-11-30 18:11:58 +01:00
EnZaXD
ddc93d7a59
1.20.3-pre4 2023-11-28 17:29:36 +01:00
EnZaXD
3a2011caab
1.20.3-pre3 2023-11-27 17:21:42 +01:00
EnZaXD
14e555c861
1.20.3-pre2 2023-11-22 18:08:41 +01:00
EnZaXD
3eb7157bf1
1.20.3-pre1 2023-11-20 19:40:38 +01:00
EnZaXD
cb0e67591e
23w46a 2023-11-20 13:59:35 +01:00
EnZaXD
fc3b03d8fb
23w45a 2023-11-10 16:03:04 +01:00
EnZaXD
ab9c735eea
Update Via* 2023-11-03 20:17:05 +01:00
FlorianMichael
c31b19c2ce
Fixed GUI rendering in all versions 2023-11-01 05:10:55 +01:00
FlorianMichael
703ead17dc
Add refmap file to output jar 2023-11-01 04:58:44 +01:00
FlorianMichael
fbc33a80d0
Don't include plugins twice 2023-11-01 04:46:50 +01:00
FlorianMichael
be8f079e26
Merge remote-tracking branch 'origin/dev' 2023-10-26 01:12:41 +02:00
FlorianMichael
9aea3aa3ac
Sync last commits to all mc version implementations 2023-10-26 01:05:26 +02:00
FlorianMichael
3cf92fa69f
Some clean up, added f3 debug hud 2023-10-25 23:17:37 +02:00
FlorianMichael
fd1b080728
Set VFNetworkManager in commons injector 2023-10-25 22:46:58 +02:00
FlorianMichael
76e8ec8baa
Added groups in config.yml
Allow to set button positions
Added system to set versions for singleton servers in the server list
Added BetaCraft MpPass for classic servers
Added per-server-version system
2023-10-25 22:42:41 +02:00
FlorianMichael
5a4b714bc5
Various changes to the protocol selection gui:
1. Add button for creating Via dumps and reloading all config files
2. Fix ESC action to actually open the parent screen
3. Made the GUI pretty
2023-10-25 03:51:41 +02:00
FlorianMichael
2e09d167bf
ViaLegacy/ViaAprilFools 😎 2023-10-25 01:58:52 +02:00
Adrian F
b43cf548c4
General improvements to the viaversion schematic. (#76) 2023-10-24 22:19:58 +02:00
FlorianMichael
4b98412388
Even more dummy classes 2023-10-24 21:29:06 +02:00
FlorianMichael
a489e42ee0
Only apply mixins on the client side 2023-10-24 16:54:58 +02:00
FlorianMichael
3fed59dbda
Added proper fix for the idle packet in <= 1.8 2023-10-24 16:51:42 +02:00
FlorianMichael
484c8ba9a8
Outsource providers 2023-10-22 00:34:57 +02:00
FlorianMichael
b5be55a0c8
Merge remote-tracking branch 'origin/master' 2023-10-21 21:51:16 +02:00
FlorianMichael
04f297e1bb
Added config to save selected protocol version and to disable ViaForge button + javadoc 2023-10-21 21:51:02 +02:00
Kichura
edaa8618a7
Remove viaforge directory dupes in CI. (#75) 2023-10-21 18:12:55 +02:00
Kichura
9f4c642b5a
Implement GH cache to CI. (#74) 2023-10-21 17:13:59 +02:00
FlorianMichael
7594239138
Explain build script structure 2023-10-21 17:10:15 +02:00
FlorianMichael
98d1aea223
Bump version to 3.5.0-SNAPSHOT 2023-10-21 16:30:32 +02:00
FlorianMichael
6fdb88b33d
Merge remote-tracking branch 'origin/master' 2023-10-21 16:08:35 +02:00
FlorianMichael
1fbc96b805
Abstract platform code, build tasks and resources / fixed loading on all versions ™️ 2023-10-21 16:08:11 +02:00
Kichura
11a77507ab
Add missing 1.14 and 1.15 to CI. (#73) 2023-10-21 14:15:07 +02:00
FlorianMichael
d015b8807e
Added Support for Minecraft 1.14 and 1.15 2023-10-21 02:40:45 +02:00
FlorianMichael
fe045d01ac
Added Support for Minecraft 1.17, 1.18, 1.19, 1.20 2023-10-21 01:27:37 +02:00
FlorianMichael
48dea35519
Added version-replacement 2023-10-21 00:21:33 +02:00
FlorianMichael
cc10575786
Fixed corrupt gradle wrapper jar file 2023-10-21 00:05:53 +02:00
FlorianMichael
4b51ddf542
Abstract build scripts 2023-10-20 23:59:21 +02:00
FlorianMichael
0641355db6
Merge remote-tracking branch 'origin/master' 2023-10-20 20:44:23 +02:00
FlorianMichael
1f69af3cf3
Added bug_report template for GitHub. 2023-10-20 20:44:09 +02:00
Kichura
21f6507dac
Clean up CI, Update Gradle and dependencies. (#72)
* Clean up CI, Update Gradle and dependencies.

* Attempt 1 on minecraftforge's gradle.

* Attempt 2 on minecraftforge's gradle.

* Go back to Gradle 7.5.1.

* Revert shadow back to 7.1.2.

* ViaForge 3.4.4, Update via* to dev builds, G1GC.
2023-10-20 20:38:36 +02:00
FlorianMichael
2cce2ade9e
Update README file 2023-10-20 20:32:08 +02:00
FlorianMichael
869352b02a
Maybe this could give us a jar file? 2023-10-20 18:39:24 +02:00
FlorianMichael
18f17e4494
Add support for Minecraft 1.16.5 ™️ 2023-10-20 18:32:52 +02:00
FlorianMichael
967930ef64
Building works now 2023-10-20 10:46:47 +02:00
FlorianMichael
5e40ef4111
Setup multi module project 2023-10-20 09:40:46 +02:00
FlorianMichael
58099058a5
clean up of the source code 2023-10-20 08:55:10 +02:00
FlorianMichael
49f6b80d70
removed debugging println 2023-10-20 08:42:58 +02:00
EnZaXD
fff800ec7d
Update mcmod.info 2023-09-22 17:55:52 +02:00
EnZaXD
f7a5eb910d
Renamed sub module 2023-09-21 22:24:44 +02:00
EnZaXD
390ffa4ccc
Bump libraries 2023-09-21 22:24:22 +02:00
EnZaXD
5443fca792
Updated description of the project 2023-08-07 01:26:11 +02:00
FlorianMichael
fcd8b19e6e
updated README 2023-06-08 21:34:43 +02:00
FlorianMichael
110264b312
Fixed ViaVersion loading 2023-06-08 21:21:48 +02:00
FlorianMichael
57fde74508
Bump version to 3.3.3 2023-06-08 20:22:54 +02:00
FlorianMichael
dbf346eef8
Fixed GUI and building 2023-06-08 20:18:39 +02:00
154 changed files with 7580 additions and 505 deletions

2
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,2 @@
github: FlorianMichael
custom: ["https://florianmichael.de/donate"]

53
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,53 @@
name: Bug Report
description: Report a bug in ViaForge
labels: [bug]
body:
- type: markdown
attributes:
value: |
**Before reporting a bug, please see if using latest build from https://github.com/ViaVersion/ViaForge/actions fixes your issue.**
Whenever you see fit, you can upload images or videos to any of the text fields.
- type: textarea
attributes:
label: General Information
description: |
Please provide a list of all installed mods
placeholder: |
Example: "ViaForge, Optifine, Xaeros Minimap, WorldEdit, WorldGuard, etc."
validations:
required: true
- type: textarea
attributes:
label: Bug Description
description: |
Describe the unexpected behavior.
If you want to attach screenshots, use the comment field at the bottom of the page.
placeholder: |
Example: "Joining server xy causes my game to crash."
validations:
required: true
- type: textarea
attributes:
label: Steps to Reproduce
description: |
List the steps on how we can reproduce the issue. Make sure I can easily understand what you mean with each step.
placeholder: |
Example:
1. Joining server xy with version 1.14.4
2. Game crashes
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: |
Describe what exactly you expected to happen.
placeholder: |
Example: "the game should not crash when I join server xy."
validations:
required: true

BIN
.github/images/ViaVersion.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

View File

@ -1,30 +1,33 @@
name: ViaForge build
name: ViaForge CI
on: [pull_request, push, workflow_dispatch]
jobs:
build:
strategy:
matrix:
java: ["8"]
os: ["ubuntu-22.04"]
runs-on: ${{ matrix.os }}
runs-on: ubuntu-22.04
steps:
- name: Checkout the repository
uses: actions/checkout@v3
- name: Validate Gradle wrapper
- name: Checkout Repository
uses: actions/checkout@v4
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v1
- name: Setup JDK ${{ matrix.java }}
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: ${{ matrix.java }}
java-version: 17
distribution: 'temurin'
- name: Make Gradle wrapper runnable on Unix
run: chmod +x ./gradlew
- name: Build
run: ./gradlew build
check-latest: true
- name: Cache Dependencies
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build with Gradle
run: ./gradlew shadowJar
- name: Upload Build Artifacts
if: ${{ runner.os == 'Linux' && matrix.java == '8' }}
uses: actions/upload-artifact@v3
with:
name: ViaForge-1.12.2
path: build/libs/
name: ViaForge All-in-One
path: viaforge-mc*/build/libs/

9
.gitignore vendored
View File

@ -1,4 +1,5 @@
# eclipse
# Eclipse
bin
*.launch
.settings
@ -6,18 +7,18 @@ bin
.classpath
.project
# idea
# Idea
out
*.ipr
*.iws
*.iml
.idea
# gradle
# Gradle
build
.gradle
# other
# Others
eclipse
run

View File

@ -0,0 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge&#10;Copyright (C) 2021-&amp;#36;today.year FlorianMichael/EnZaXD &lt;florian.michael07@gmail.com&gt; and contributors&#10;&#10;This program is free software: you can redistribute it and/or modify&#10;it under the terms of the GNU General Public License as published by&#10;the Free Software Foundation, either version 3 of the License, or&#10;(at your option) any later version.&#10;&#10;This program is distributed in the hope that it will be useful,&#10;but WITHOUT ANY WARRANTY; without even the implied warranty of&#10;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#10;GNU General Public License for more details.&#10;&#10;You should have received a copy of the GNU General Public License&#10;along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;." />
<option name="myName" value="GPL-3.0" />
</copyright>
</component>

View File

@ -0,0 +1,8 @@
<component name="CopyrightManager">
<settings default="GPL_3_0">
<module2copyright>
<element module="Project Files" copyright="GPL-3.0" />
</module2copyright>
<LanguageOptions name="__TEMPLATE__" />
</settings>
</component>

4
CHANGELOG.md Normal file
View File

@ -0,0 +1,4 @@
- Updated Via* projects to support 1.20.5
- Fixed version in 1.12 mcmod.info file
- Fixed connecting issues and other desyncs
- Fixed pre netty versions not working on online servers

View File

@ -1,40 +1,52 @@
# ViaForge
Client-side Implementation of ViaVersion for Forge
Client-side Implementation of the Via* projects for Minecraft Forge
## Contact
If you encounter any issues, please report them on the
[issue tracker](https://github.com/FlorianMichael/ViaForge/issues).
[issue tracker](https://github.com/ViaVersion/ViaForge/issues).
If you just want to talk or need help with ViaForge feel free to join the ViaVersion
[Discord](https://discord.gg/viaversion).
## For users
### Where can I download the latest version?
CurseForge: https://www.curseforge.com/minecraft/mc-mods/viaforge
Modrinth: https://modrinth.com/mod/viaforge
### Can you add new textures and blocks from higher versions?
No, because it is too time-consuming
GitHub Releases: https://github.com/ViaVersion/ViaForge
### ViaVersion throws an error, or I can't access a server, what should I do?
First of all see if it's because of an installed mod, otherwise come to the support Discord and tell me logs, mc version etc.
### Certain collisions or other items bug, can you fix it?
No
### How does it work?
![](.github/images/ViaVersion.png)
## For developers
### How does it work?
![](images/via-expl.png)
### Project Structure
All ViaForge versions from Minecraft version 1.12 onwards are on the `master` branch. <br>
All ViaForge versions from Minecraft version 1.12.2 onwards are on the `master` branch. <br>
The names of the submodules indicate the version, they are always given in the format `mc-<version name without .>`. <br>
`Minecraft 1.12.2` - `mc1122`
`Minecraft 1.12.2` - `viaforge-mc1122` <br>
`Minecraft 1.16.5` - `viaforge-mc1165` <br>
`Minecraft 1.17.1` - `viaforge-mc1171` <br>
`Minecraft 1.18.2` - `viaforge-mc1182` <br>
`Minecraft 1.19.4` - `viaforge-mc1194` <br>
`Minecraft 1.20.4` - `viaforge-mc1204` <br>
### ViaForge for Minecraft 1.8
Since ForgeGradle for Minecraft 1.8 is too old, it has its own branch called `legacy-1.8`
Since ForgeGradle for Minecraft 1.8.9 is too old, it has its own branch called `legacy-1.8`
### I want ViaForge in my own utility mod
Just take a look at my other Project called `ViaMCP`: https://github.com/FlorianMichael/ViaMCP
## Other Via related Projects
ViaFabric - Clientside Via implementation for Fabric: https://www.curseforge.com/minecraft/mc-mods/viafabric
## For developers
### How to build
1. Clone the repository with `git clone`.
2. Run `./gradlew build` in the root directory of the repository.
3. The compiled jar files can be found in `viaforge-mc<version>/build/libs`.
Note: Build scripts are made to be run using Java 17.
## Other ViaVersion Mods / Platforms
- ViaFabric - https://modrinth.com/mod/viafabric
- ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus (Includes additional modifications to make the experience better)
- ViaProxy (App) - https://github.com/ViaVersion/ViaProxy
- ViaaaS (Proxy) - https://github.com/ViaVersion/ViaaaS
### If you want to talk with me, feel free to join my [Discord](https://discord.gg/BwWhCHUKDf)

View File

@ -1,3 +1,225 @@
plugins {
id "java"
buildscript {
repositories {
gradlePluginPortal()
maven { url = "https://repo.spongepowered.org/repository/maven-public/" }
maven { url = "https://jitpack.io/" }
maven { url = "https://files.minecraftforge.net/maven" }
}
dependencies {
classpath "com.github.johnrengelman:shadow:7.1.2"
classpath "net.minecraftforge.gradle:ForgeGradle:6.+"
classpath "org.spongepowered:mixingradle:0.7-SNAPSHOT"
classpath "me.modmuss50:mod-publish-plugin:0.5.1"
classpath "xyz.wagyourtail.jvmdowngrader:gradle-plugin:0.6.1"
}
}
allprojects {
apply plugin: "java-library"
apply plugin: "com.github.johnrengelman.shadow"
apply plugin: "me.modmuss50.mod-publish-plugin"
apply plugin: "xyz.wagyourtail.jvmdowngrader"
java {
// Minecraft 1.17+ required Java 16/17 to compile
toolchain.languageVersion = JavaLanguageVersion.of(17)
}
// We define the configuration here so we can use it across all conventions and platforms
// To define which projects/source files should be included in the jar
configurations {
library
implementation.extendsFrom(library)
}
// Repositories for the ViaVersion dependencies defined below
repositories {
maven {
url = "https://repo.spongepowered.org/repository/maven-public"
}
maven {
url = "https://repo.viaversion.com"
metadataSources {
mavenPom()
artifact()
}
}
}
// Replace the version in the mcmod.info and mods.toml files with the project version
// Since this depends on the platform version, we can't define it in the global scope :(
tasks {
processResources {
for (final def file in ["mcmod.info", "META-INF/mods.toml"]) {
filesMatching(file) {
expand "version": project.version
}
}
}
}
// Including all required libraries for ViaVersion {for version numbers see gradle.properties}
dependencies {
compileOnly "io.netty:netty-all:4.0.20.Final"
library "com.viaversion:viaversion-common:${project.viaversion_version}"
library "com.viaversion:viabackwards-common:${project.viabackwards_version}"
library "com.viaversion:viarewind-common:${project.viarewind_version}"
library ("net.raphimc:ViaLegacy:${project.vialegacy_version}") {
exclude group: "com.google.code.gson", module: "gson"
}
library "net.raphimc:ViaAprilFools:${project.viaaprilfools_version}"
library ("net.raphimc:ViaLoader:${project.vialoader_version}") {
exclude group: "com.google.guava"
exclude group: "org.slf4j"
}
library "org.yaml:snakeyaml:${project.snake_yml_version}"
}
}
subprojects {
apply plugin: "net.minecraftforge.gradle"
apply plugin: "org.spongepowered.mixin"
// Define the jar output attributes for all platforms
archivesBaseName = project.maven_name
version = maven_version
group = maven_group
// Used to execute code only for specific submodules
def versionId = Integer.parseInt(project.mc_version.replace(".", ""))
compileJava.options.encoding = "UTF-8"
minecraft {
runs {
client {
workingDirectory project.file("run")
property "forge.logging.markers", "REGISTRIES"
property "forge.logging.console.level", "debug"
// mixin
property "mixin.debug.export", "true"
property "mixin.hotSwap", "true"
property "fml.coreMods.load", "de.florianmichael.viaforge.mixin.MixinLoader" // Only required for MC 1.12, but modern Forges skips this anyway
args "-mixin.config=" + "mixins." + project.getProperty('maven_name') + ".json"
// source set
mods {
"${project.maven_name}" {
source sourceSets.main
}
}
}
}
}
sourceSets.main.resources {
srcDir "src/generated/resources"
}
dependencies {
if (versionId >= 1_17_1) {
// Minecraft 1.17+ already includes slf4j, so we don't need to include it
compileOnly "org.slf4j:slf4j-api:${slf4j_version}"
} else {
library "org.slf4j:slf4j-api:${slf4j_version}"
}
library "org.spongepowered:mixin:${mixin_version}"
annotationProcessor "org.spongepowered:mixin:${mixin_version}:processor"
library project(":") // Include the base project, to get Common-ViaForge
}
mixin {
add sourceSets.main, "mixins.${project.maven_name}.refmap.json"
}
jar {
manifest.attributes(
"Specification-Title": "viaforge",
"Specification-Vendor": "viaforge",
"Specification-Version": project.version,
"Implementation-Title": project.name,
"Implementation-Version": project.version,
"Implementation-Vendor" :"viaforge",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd"-"HH:mm:ssZ"),
"TweakClass": "org.spongepowered.asm.launch.MixinTweaker",
"TweakOrder": "0",
"FMLCorePluginContainsFMLMod": "true", // Only required for MC 1.12, but modern Forges skips this anyway
"FMLCorePlugin": "de.florianmichael.viaforge.mixin.MixinLoader", // Counterpart to the above
"MixinConfigs": "mixins.${project.maven_name}.json",
"ForceLoadAsMod": "true"
)
enabled = false
}
shadowJar {
if (versionId >= 1_17_1) {
archiveFileName = jar.archiveFileName
} else {
destinationDirectory = temporaryDir
}
configurations = [project.configurations.library] // Include the dependencies from the include configuration
duplicatesStrategy DuplicatesStrategy.EXCLUDE
// Prevent conflicts with Forge's weird service loading
exclude("META-INF/maven/**")
exclude("META-INF/versions/**")
if (versionId >= 1_13_2) {
// We don't need to package mixins into Forge 1.13+ jars, since Forge already has it
exclude("org/spongepowered/**")
}
if (versionId >= 1_16_5) {
// Get rid of the services folder, since Forge 1.16+ would conflict with some of the ForgeDev Environment's services
// And since we don't need them for Mixins anyway, we can just exclude them from the shadowJar
exclude("META-INF/services/**")
}
}
downgradeJar {
inputFile = shadowJar.archiveFile
destinationDirectory = temporaryDir
}
shadeDowngradedApi {
archiveFileName = jar.archiveFileName
}
publishMods {
file = shadowJar.archiveFile
type = STABLE
displayName = rootProject.name + ' ' + project.version
version = project.version + "+" + project.mc_version
modLoaders.add("forge")
changelog = file("../CHANGELOG.md").text
dryRun = rootProject.maven_version.contains("SNAPSHOT")
curseforge {
accessToken = providers.gradleProperty("curseforge.publishing_token")
projectId = "418933"
minecraftVersions.addAll(project.mc_version.split(','))
}
modrinth {
accessToken = providers.gradleProperty("modrinth.publishing_token")
projectId = "Z6se2s8f"
minecraftVersions.addAll(project.mc_version.split(','))
}
}
reobf {
shadowJar {}
}
jar.dependsOn("shadowJar")
if (versionId < 1_17_1) {
// Downgrade the jar to Java 8 for Minecraft 1.16.5 and below
jar.dependsOn("shadeDowngradedApi")
}
}

View File

@ -1,19 +1,21 @@
# java
org.gradle.jvmargs=-Xmx3G
# Gradle Properties
org.gradle.jvmargs=-Xmx3G -XX:+UseG1GC
org.gradle.daemon=false
# forge
mod_id=viaforge
mod_name=ViaForge
mod_version=3.3.2
mod_base_package=de.florianmichael
# Project Details
maven_version=3.7.1-SNAPSHOT
maven_group=de.florianmichael
# mixin
# ViaVersion
viaversion_version=5.0.1-SNAPSHOT
viabackwards_version=5.0.1-SNAPSHOT
viarewind_version=4.0.0
vialegacy_version=3.0.1-SNAPSHOT
viaaprilfools_version=3.0.1-SNAPSHOT
vialoader_version=3.0.1-SNAPSHOT
snake_yml_version=2.2
# Misc Libraries
slf4j_version=2.0.7
mixin_version=0.8.3
# via-version
vialoader_version=2.2.5-SNAPSHOT
viaversion_version=4.7.0
viabackwards_version=4.7.0
viarewind_version=2.0.4-SNAPSHOT
snake_yml_version=2.0

Binary file not shown.

View File

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

51
gradlew vendored
View File

@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@ -32,10 +32,10 @@
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@ -80,13 +80,11 @@ do
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@ -133,22 +131,29 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
@ -205,6 +214,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.

35
gradlew.bat vendored
View File

@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@ -25,7 +25,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@ -40,13 +41,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@ -56,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

View File

@ -1,147 +0,0 @@
buildscript {
repositories {
mavenCentral()
gradlePluginPortal()
maven { url = "https://maven.minecraftforge.net/" }
maven { url = "https://repo.spongepowered.org/repository/maven-public/" }
maven { url = "https://jitpack.io/" }
maven { url = "https://files.minecraftforge.net/maven" }
maven { url = "https://plugins.gradle.org/m2" }
}
dependencies {
classpath "net.minecraftforge.gradle:ForgeGradle:5.1.+"
classpath "org.spongepowered:mixingradle:0.7-SNAPSHOT"
classpath "com.github.johnrengelman:shadow:7.0.0"
}
}
apply plugin: "net.minecraftforge.gradle"
apply plugin: "org.spongepowered.mixin"
apply plugin: "com.github.johnrengelman.shadow"
apply plugin: "java"
version = "1.12.2-${mod_version}"
group = "${mod_base_package}.${mod_id}"
archivesBaseName = mod_id
java.toolchain.languageVersion = JavaLanguageVersion.of(8)
compileJava.options.encoding = "UTF-8"
minecraft {
mappings channel: "stable", version: "39-1.12"
runs {
client {
workingDirectory project.file("run")
property 'forge.logging.markers', 'REGISTRIES'
property "forge.logging.console.level", "debug"
// mixin
property 'mixin.debug.export', 'true'
property "mixin.hotSwap", "true"
property "fml.coreMods.load", "de.florianmichael.viaforge.mixin.MixinLoader"
if (project.hasProperty('mc_uuid'))
args '--uuid', project.getProperty('mc_uuid')
if (project.hasProperty('mc_username'))
args '--username', project.getProperty('mc_username')
if (project.hasProperty('mc_accessToken'))
args '--accessToken', project.getProperty('mc_accessToken')
args '-mixin.config=' + 'mixins.' + project.getProperty('mod_id') + '.json'
mods {
"${mod_id}" {
source sourceSets.main
}
}
}
}
}
sourceSets.main.resources {
srcDir "src/generated/resources"
}
repositories {
maven {
url = "https://repo.spongepowered.org/repository/maven-public"
}
maven {
url = "https://repo.viaversion.com"
}
}
configurations {
include
implementation.extendsFrom(include)
}
def viaLibs = [
"com.viaversion:viaversion:${project.viaversion_version}",
"com.viaversion:viabackwards:${project.viabackwards_version}",
"com.viaversion:viarewind-core:${project.viarewind_version}",
"org.yaml:snakeyaml:${project.snake_yml_version}",
"net.raphimc:ViaLoader:${project.vialoader_version}"
]
dependencies {
minecraft "net.minecraftforge:forge:1.12.2-14.23.5.2859"
include "org.spongepowered:mixin:${mixin_version}"
for (final def via in viaLibs) {
implementation(via)
}
annotationProcessor "org.spongepowered:mixin:${mixin_version}:processor"
annotationProcessor "org.spongepowered:mixin:${mixin_version}:processor"
}
mixin {
add sourceSets.main, "mixins.${mod_id}.refmap.json"
}
jar {
manifest.attributes(
"Specification-Title": "viaforge",
"Specification-Vendor": "viaforge",
"Specification-Version": "1",
"Implementation-Title": project.name,
"Implementation-Version": "${archiveVersion}",
"Implementation-Vendor" :"viaforge",
"Implementation-Timestamp": new Date().format("yyyy-MM-dd"-"HH:mm:ssZ"),
"TweakClass": "org.spongepowered.asm.launch.MixinTweaker",
"TweakOrder": "0",
"FMLCorePluginContainsFMLMod": "true",
"FMLCorePlugin": "de.florianmichael.viaforge.mixin.MixinLoader",
"MixinConfigs": "mixins.${mod_id}.json",
"ForceLoadAsMod": "true"
)
enabled = false
}
shadowJar {
archiveFileName = jar.archiveFileName
compileJava.options.encoding = "UTF-8"
exclude "native-binaries/*"
dependencies {
for (final def lib in viaLibs) {
include(dependency(lib))
}
include(dependency("org.spongepowered:mixin:${mixin_version}"))
}
}
reobf {
shadowJar {}
}
jar.dependsOn("shadowJar")

View File

@ -1,63 +0,0 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.VersionProvider;
import com.viaversion.viaversion.protocols.base.BaseVersionProvider;
import net.minecraft.client.Minecraft;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.raphimc.vialoader.ViaLoader;
import net.raphimc.vialoader.impl.platform.ViaBackwardsPlatformImpl;
import net.raphimc.vialoader.impl.platform.ViaRewindPlatformImpl;
import net.raphimc.vialoader.impl.viaversion.VLLoader;
import net.raphimc.vialoader.util.VersionEnum;
@Mod(modid = "viaforge", name = "ViaForge", version = "3.3.2")
public class ViaForge {
public final static VersionEnum NATIVE_VERSION = VersionEnum.r1_12_2;
public static VersionEnum targetVersion = VersionEnum.r1_12_2;
@Mod.EventHandler
public void init(FMLPreInitializationEvent event) {
ViaLoader.init(
null,
new VLLoader() {
@Override
public void load() {
super.load();
Via.getManager().getProviders().use(VersionProvider.class, new BaseVersionProvider() {
@Override
public int getClosestServerProtocol(UserConnection connection) throws Exception {
if (connection.isClientSide() && !Minecraft.getMinecraft().isSingleplayer()) {
return targetVersion.getVersion();
}
return super.getClosestServerProtocol(connection);
}
});
}
},
null,
null,
ViaBackwardsPlatformImpl::new, ViaRewindPlatformImpl::new
);
}
}

View File

@ -1,108 +0,0 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.gui;
import com.mojang.realmsclient.gui.ChatFormatting;
import de.florianmichael.viaforge.ViaForge;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiSlot;
import net.raphimc.vialoader.util.VersionEnum;
import org.lwjgl.opengl.GL11;
import java.io.IOException;
public class GuiProtocolSelector extends GuiScreen {
private final GuiScreen parent;
private SlotList list;
public GuiProtocolSelector(GuiScreen parent) {
this.parent = parent;
}
@Override
public void initGui() {
super.initGui();
buttonList.add(new GuiButton(1, width / 2 - 100, height - 27, 200, 20, "Back"));
list = new SlotList(mc, width, height, 32, height - 32, 10);
}
@Override
protected void actionPerformed(GuiButton p_actionPerformed_1_) throws IOException {
list.actionPerformed(p_actionPerformed_1_);
if (p_actionPerformed_1_.id == 1) mc.displayGuiScreen(parent);
}
@Override
public void handleMouseInput() throws IOException {
list.handleMouseInput();
super.handleMouseInput();
}
@Override
public void drawScreen(int p_drawScreen_1_, int p_drawScreen_2_, float p_drawScreen_3_) {
list.drawScreen(p_drawScreen_1_, p_drawScreen_2_, p_drawScreen_3_);
GL11.glPushMatrix();
GL11.glScalef(2.0F, 2.0F, 2.0F);
this.drawCenteredString(this.fontRenderer, ChatFormatting.GOLD + "ViaForge", this.width / 4, 6, 16777215);
GL11.glPopMatrix();
drawString(this.fontRenderer, "by https://github.com/FlorianMichael/ViaForge", 1, 1, -1);
drawString(this.fontRenderer, "Discord: EnZaXD#6257", 1, 11, -1);
super.drawScreen(p_drawScreen_1_, p_drawScreen_2_, p_drawScreen_3_);
}
class SlotList extends GuiSlot {
public SlotList(Minecraft p_i1052_1_, int p_i1052_2_, int p_i1052_3_, int p_i1052_4_, int p_i1052_5_, int p_i1052_6_) {
super(p_i1052_1_, p_i1052_2_, p_i1052_3_, p_i1052_4_, p_i1052_5_, p_i1052_6_);
}
@Override
protected int getSize() {
return VersionEnum.OFFICIAL_SUPPORTED_PROTOCOLS.size();
}
@Override
protected void elementClicked(int i, boolean b, int i1, int i2) {
ViaForge.targetVersion = VersionEnum.OFFICIAL_SUPPORTED_PROTOCOLS.get(i);
}
@Override
protected boolean isSelected(int i) {
return false;
}
@Override
protected void drawBackground() {
drawDefaultBackground();
}
@Override
protected void drawSlot(int i, int i1, int i2, int i3, int i4, int i5, float v) {
final VersionEnum version = VersionEnum.OFFICIAL_SUPPORTED_PROTOCOLS.get(i);
drawCenteredString(mc.fontRenderer,(ViaForge.targetVersion.getVersion() == version.getVersion() ? ChatFormatting.GREEN.toString() : ChatFormatting.DARK_RED.toString()) + version.getName(), width / 2, i2, -1);
}
}
}

View File

@ -1,16 +0,0 @@
[
{
"modid": "viaforge",
"name": "ViaForge",
"description": "Client-side Implementation of ViaVersion for Forge",
"version": "1.0.0",
"mcversion": "[1.8,1.12.2]",
"url": "https://github.com/FlorianMichael/ViaForge",
"updateUrl": "",
"authorList": [],
"credits": "",
"logoFile": "",
"screenshots": [],
"dependencies": []
}
]

View File

@ -1,15 +0,0 @@
{
"required": true,
"minVersion": "0.7.5",
"compatibilityLevel": "JAVA_8",
"package": "de.florianmichael.viaforge.mixin.impl",
"refmap": "mixins.viaforge.refmap.json",
"mixins": [
"MixinNetworkManager",
"MixinNetworkManager_5",
"MixinGuiMainMenu",
"MixinGuiMultiplayer",
"MixinGuiScreenServerList"
],
"verbose": true
}

View File

@ -1,3 +1,12 @@
rootProject.name = "ViaForge"
include 'mc1122'
plugins {
id "org.gradle.toolchains.foojay-resolver-convention" version "0.8.0"
}
rootProject.name = "ViaForge"
include "viaforge-mc1122"
include "viaforge-mc1165"
include "viaforge-mc1171"
include "viaforge-mc1182"
include "viaforge-mc1194"
include "viaforge-mc1204"

View File

@ -0,0 +1,159 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.common;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
import de.florianmichael.viaforge.common.platform.VFPlatform;
import de.florianmichael.viaforge.common.platform.ViaForgeConfig;
import de.florianmichael.viaforge.common.protocoltranslator.ViaForgeVLInjector;
import de.florianmichael.viaforge.common.protocoltranslator.ViaForgeVLLoader;
import de.florianmichael.viaforge.common.protocoltranslator.netty.VFNetworkManager;
import de.florianmichael.viaforge.common.protocoltranslator.netty.ViaForgeVLLegacyPipeline;
import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import net.raphimc.vialoader.ViaLoader;
import net.raphimc.vialoader.impl.platform.*;
import net.raphimc.vialoader.netty.CompressionReorderEvent;
import java.io.File;
/**
* This class is used to manage the common code between the different ViaForge versions.
* It is used to inject the ViaVersion pipeline into the netty pipeline. It also manages the target version.
*/
public class ViaForgeCommon {
public static final AttributeKey<UserConnection> LOCAL_VIA_USER = AttributeKey.valueOf("local_via_user");
public static final AttributeKey<VFNetworkManager> VF_NETWORK_MANAGER = AttributeKey.valueOf("encryption_setup");
private static ViaForgeCommon manager;
private final VFPlatform platform;
private ProtocolVersion targetVersion;
private ProtocolVersion previousVersion;
private ViaForgeConfig config;
public ViaForgeCommon(VFPlatform platform) {
this.platform = platform;
}
/**
* Initializes the manager.
*
* @param platform the platform fields
*/
public static void init(final VFPlatform platform) {
final ProtocolVersion version = ProtocolVersion.getProtocol(platform.getGameVersion()); // ViaForge will only load on post-netty versions
if (version == ProtocolVersion.unknown) {
throw new IllegalArgumentException("Unknown version " + platform.getGameVersion());
}
manager = new ViaForgeCommon(platform);
final File mainFolder = new File(platform.getLeadingDirectory(), "ViaForge");
ViaLoader.init(new ViaVersionPlatformImpl(mainFolder), new ViaForgeVLLoader(platform), new ViaForgeVLInjector(), null, ViaBackwardsPlatformImpl::new, ViaRewindPlatformImpl::new, ViaLegacyPlatformImpl::new, ViaAprilFoolsPlatformImpl::new);
manager.config = new ViaForgeConfig(new File(mainFolder, "viaforge.yml"), Via.getPlatform().getLogger());
final ProtocolVersion configVersion = ProtocolVersion.getClosest(manager.config.getClientSideVersion());
if (configVersion != null) {
manager.setTargetVersion(configVersion);
} else {
manager.setTargetVersion(version);
}
}
/**
* Injects the ViaVersion pipeline into the netty pipeline.
*
* @param channel the channel to inject the pipeline into
*/
public void inject(final Channel channel, final VFNetworkManager networkManager) {
if (networkManager.viaForge$getTrackedVersion().equals(getNativeVersion())) {
return; // Don't inject ViaVersion into pipeline if there is nothing to translate anyway
}
channel.attr(VF_NETWORK_MANAGER).set(networkManager);
final UserConnection user = new UserConnectionImpl(channel, true);
new ProtocolPipelineImpl(user);
channel.attr(LOCAL_VIA_USER).set(user);
channel.pipeline().addLast(new ViaForgeVLLegacyPipeline(user, targetVersion));
channel.closeFuture().addListener(future -> {
if (previousVersion != null) {
restoreVersion();
}
});
}
/**
* Reorders the compression channel.
*
* @param channel the channel to reorder the compression for
*/
public void reorderCompression(final Channel channel) {
// When Minecraft enables compression, we need to reorder the pipeline
// to match the counterparts of via-decoder <-> encoder and via-encoder <-> encoder
channel.pipeline().fireUserEventTriggered(CompressionReorderEvent.INSTANCE);
}
public ProtocolVersion getNativeVersion() {
return ProtocolVersion.getProtocol(platform.getGameVersion());
}
public ProtocolVersion getTargetVersion() {
return targetVersion;
}
public void restoreVersion() {
this.targetVersion = ProtocolVersion.getClosest(config.getClientSideVersion());
}
public void setTargetVersionSilent(final ProtocolVersion targetVersion) {
final ProtocolVersion oldVersion = this.targetVersion;
this.targetVersion = targetVersion;
if (oldVersion != targetVersion) {
previousVersion = oldVersion;
}
}
public void setTargetVersion(final ProtocolVersion targetVersion) {
this.targetVersion = targetVersion;
config.setClientSideVersion(targetVersion.getName());
}
public VFPlatform getPlatform() {
return platform;
}
public ViaForgeConfig getConfig() {
return config;
}
public static ViaForgeCommon getManager() {
return manager;
}
}

View File

@ -0,0 +1,32 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.common.gui;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
/**
* This interface is used to store the target version for a specific server in the server list.
*/
public interface ExtendedServerData {
ProtocolVersion viaForge$getVersion();
void viaForge$setVersion(final ProtocolVersion version);
}

View File

@ -0,0 +1,58 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.common.platform;
import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.provider.GameProfileFetcher;
import java.io.File;
import java.util.function.Supplier;
/**
* This interface is used to access platform-specific fields.
*/
public interface VFPlatform {
/**
* @return the native version of the platform
*/
int getGameVersion();
/**
* @return if the client is in singleplayer
*/
Supplier<Boolean> isSingleplayer();
/**
* @return the leading directory of the platform
*/
File getLeadingDirectory();
/**
* Sends the joinServer API request to Mojang's authentication servers.
*
* @param serverId the server id of the server
*/
void joinServer(final String serverId) throws Throwable;
/**
* @return the game profile fetcher of the platform for ViaLegacy
*/
GameProfileFetcher getGameProfileFetcher();
}

View File

@ -0,0 +1,44 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.common.platform;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
/**
* Dirty, but needed to store the server specific version until building the netty pipeline.
*/
public class VersionTracker {
public static final Map<InetAddress, ProtocolVersion> SERVER_PROTOCOL_VERSIONS = new HashMap<>();
public static void storeServerProtocolVersion(InetAddress address, ProtocolVersion version) {
SERVER_PROTOCOL_VERSIONS.put(address, version);
ViaForgeCommon.getManager().setTargetVersionSilent(version);
}
public static ProtocolVersion getServerProtocolVersion(InetAddress address) {
return SERVER_PROTOCOL_VERSIONS.remove(address);
}
}

View File

@ -0,0 +1,148 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.common.platform;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.util.Config;
import com.viaversion.viaversion.util.Pair;
import java.io.File;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
public class ViaForgeConfig extends Config {
public static final String CLIENT_SIDE_VERSION = "client-side-version";
public static final String VERIFY_SESSION_IN_OLD_VERSIONS = "verify-session-in-old-versions";
public static final String ALLOW_BETACRAFT_AUTHENTICATION = "allow-betacraft-authentication";
public static final String SHOW_PROTOCOL_VERSION_IN_F3 = "show-protocol-version-in-f3";
public static final String SHOW_MAIN_MENU_BUTTON = "show-main-menu-button";
public static final String SHOW_MULTIPLAYER_BUTTON = "show-multiplayer-button";
public static final String SHOW_DIRECT_CONNECT_BUTTON = "show-direct-connect-button";
public static final String SHOW_ADD_SERVER_BUTTON = "show-add-server-button";
public static final String VIA_FORGE_BUTTON_POSITION = "via-forge-button-position";
public static final String ADD_SERVER_SCREEN_BUTTON_POSITION = "add-server-screen-button-position";
/**
* @param configFile The location of where the config is loaded/saved.
*/
public ViaForgeConfig(File configFile, Logger logger) {
super(configFile, logger);
reload();
}
@Override
public URL getDefaultConfigURL() {
return getClass().getClassLoader().getResource("assets/viaforge/config.yml");
}
@Override
protected void handleConfig(Map<String, Object> config) {
}
@Override
public List<String> getUnsupportedOptions() {
return Collections.emptyList();
}
@Override
public void set(String path, Object value) {
super.set(path, value);
save(); // Automatically save the config when something changes
}
public String getClientSideVersion() {
if (getInt(CLIENT_SIDE_VERSION, -1) != -1) { // Temporary fix for old configs
return ProtocolVersion.getProtocol(getInt(CLIENT_SIDE_VERSION, -1)).getName();
}
return getString(CLIENT_SIDE_VERSION, "");
}
public void setClientSideVersion(final String version) {
set(CLIENT_SIDE_VERSION, version);
}
public boolean isVerifySessionInOldVersions() {
return getBoolean(VERIFY_SESSION_IN_OLD_VERSIONS, true);
}
public boolean isAllowBetacraftAuthentication() {
return getBoolean(ALLOW_BETACRAFT_AUTHENTICATION, true);
}
public boolean isShowProtocolVersionInF3() {
return getBoolean(SHOW_PROTOCOL_VERSION_IN_F3, true);
}
public boolean isShowMainMenuButton() {
return getBoolean(SHOW_MAIN_MENU_BUTTON, true);
}
public boolean isShowMultiplayerButton() {
return getBoolean(SHOW_MULTIPLAYER_BUTTON, true);
}
public boolean isShowDirectConnectButton() {
return getBoolean(SHOW_DIRECT_CONNECT_BUTTON, true);
}
public boolean isShowAddServerButton() {
return getBoolean(SHOW_ADD_SERVER_BUTTON, true);
}
public ButtonPosition getViaForgeButtonPosition() {
return ButtonPosition.valueOf(getString(VIA_FORGE_BUTTON_POSITION, ButtonPosition.TOP_LEFT.name()));
}
public ButtonPosition getAddServerScreenButtonPosition() {
return ButtonPosition.valueOf(getString(ADD_SERVER_SCREEN_BUTTON_POSITION, ButtonPosition.TOP_LEFT.name()));
}
public enum ButtonPosition {
// Button width: 100
// Button height: 20
// Button margin for both coordinates: 5
TOP_LEFT((width, height) -> new Pair<>(5, 5)),
TOP_RIGHT((width, height) -> new Pair<>(width - 100 - 5, 5)),
BOTTOM_LEFT((width, height) -> new Pair<>(5, height - 20 - 5)),
BOTTOM_RIGHT((width, height) -> new Pair<>(width - 100 - 5, height - 20 - 5));
private final PositionInvoker invoker;
ButtonPosition(final PositionInvoker invoker) {
this.invoker = invoker;
}
public Pair<Integer, Integer> getPosition(int width, int height) {
return invoker.invoke(width, height);
}
public interface PositionInvoker {
Pair<Integer, Integer> invoke(int width, int height);
}
}
}

View File

@ -0,0 +1,36 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.common.protocoltranslator;
import net.raphimc.vialoader.impl.viaversion.VLInjector;
import net.raphimc.vialoader.netty.VLLegacyPipeline;
public class ViaForgeVLInjector extends VLInjector {
@Override
public String getDecoderName() {
return VLLegacyPipeline.VIA_DECODER_NAME;
}
@Override
public String getEncoderName() {
return VLLegacyPipeline.VIA_ENCODER_NAME;
}
}

View File

@ -0,0 +1,55 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.common.protocoltranslator;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.platform.providers.ViaProviders;
import com.viaversion.viaversion.api.protocol.version.VersionProvider;
import com.viaversion.viaversion.protocols.v1_8to1_9.provider.MovementTransmitterProvider;
import de.florianmichael.viaforge.common.platform.VFPlatform;
import de.florianmichael.viaforge.common.protocoltranslator.provider.*;
import net.raphimc.vialegacy.protocol.classic.c0_28_30toa1_0_15.provider.ClassicMPPassProvider;
import net.raphimc.vialegacy.protocol.release.r1_2_4_5tor1_3_1_2.provider.OldAuthProvider;
import net.raphimc.vialegacy.protocol.release.r1_6_4tor1_7_2_5.provider.EncryptionProvider;
import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.provider.GameProfileFetcher;
import net.raphimc.vialoader.impl.viaversion.VLLoader;
public class ViaForgeVLLoader extends VLLoader {
private final VFPlatform platform;
public ViaForgeVLLoader(VFPlatform platform) {
this.platform = platform;
}
@Override
public void load() {
super.load();
final ViaProviders providers = Via.getManager().getProviders();
providers.use(VersionProvider.class, new ViaForgeVersionProvider());
providers.use(MovementTransmitterProvider.class, new ViaForgeMovementTransmitterProvider());
providers.use(OldAuthProvider.class, new ViaForgeOldAuthProvider());
providers.use(GameProfileFetcher.class, platform.getGameProfileFetcher());
providers.use(EncryptionProvider.class, new ViaForgeEncryptionProvider());
providers.use(ClassicMPPassProvider.class, new ViaForgeClassicMPPassProvider());
}
}

View File

@ -0,0 +1,43 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.common.protocoltranslator.netty;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
public interface VFNetworkManager {
/**
* API method to setup the decryption side of the pipeline.
* This method is called by the {@link de.florianmichael.viaforge.common.protocoltranslator.provider.ViaForgeEncryptionProvider} class.
*/
void viaForge$setupPreNettyDecryption();
/**
* @return the target version of the connection
*/
ProtocolVersion viaForge$getTrackedVersion();
/**
* Sets the target version of the connection.
*
* @param version the target version
*/
void viaForge$setTrackedVersion(final ProtocolVersion version);
}

View File

@ -1,6 +1,6 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,15 +15,16 @@
* 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.viaforge;
package de.florianmichael.viaforge.common.protocoltranslator.netty;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.raphimc.vialoader.netty.VLLegacyPipeline;
import net.raphimc.vialoader.util.VersionEnum;
public class ViaForgeVLLegacyPipeline extends VLLegacyPipeline {
public ViaForgeVLLegacyPipeline(UserConnection user, VersionEnum version) {
public ViaForgeVLLegacyPipeline(UserConnection user, ProtocolVersion version) {
super(user, version);
}
@ -56,4 +57,5 @@ public class ViaForgeVLLegacyPipeline extends VLLegacyPipeline {
protected String lengthPrependerName() {
return "prepender";
}
}

View File

@ -0,0 +1,88 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.common.protocoltranslator.provider;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import net.raphimc.vialegacy.protocol.classic.c0_28_30toa1_0_15.provider.ClassicMPPassProvider;
import net.raphimc.vialegacy.protocol.release.r1_2_4_5tor1_3_1_2.provider.OldAuthProvider;
import net.raphimc.vialegacy.protocol.release.r1_6_4tor1_7_2_5.storage.HandshakeStorage;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.URL;
import java.security.MessageDigest;
import java.util.Formatter;
import java.util.Scanner;
import java.util.logging.Level;
public class ViaForgeClassicMPPassProvider extends ClassicMPPassProvider {
@Override
public String getMpPass(UserConnection user) {
if (ViaForgeCommon.getManager().getConfig().isAllowBetacraftAuthentication()) {
final HandshakeStorage handshakeStorage = user.get(HandshakeStorage.class);
return getBetacraftMpPass(user, user.getProtocolInfo().getUsername(), handshakeStorage.getHostname(), handshakeStorage.getPort());
}
return super.getMpPass(user);
}
/*
Stolen from https://github.com/FlorianMichael/Classic4J/blob/main/src/main/java/de/florianmichael/classic4j/BetaCraftHandler.java :tm:
*/
private static String getBetacraftMpPass(final UserConnection user, final String username, final String ip, final int port) {
try {
final String server = InetAddress.getByName(ip).getHostAddress() + ":" + port;
Via.getManager().getProviders().get(OldAuthProvider.class).sendAuthRequest(user, sha1(server.getBytes()));
final InputStream connection = new URL("https://api.betacraft.uk/getmppass.jsp?user=" + username + "&server=" + server).openStream();
Scanner scanner = new Scanner(connection);
StringBuilder response = new StringBuilder();
while (scanner.hasNext()) {
response.append(scanner.next());
}
connection.close();
if (response.toString().contains("FAILED") || response.toString().contains("SERVER NOT FOUND")) return "0";
return response.toString();
} catch (Throwable t) {
Via.getPlatform().getLogger().log(Level.WARNING, "An unknown error occurred while authenticating with BetaCraft", t);
return "0";
}
}
private static String sha1(final byte[] input) {
try {
Formatter formatter = new Formatter();
final byte[] hash = MessageDigest.getInstance("SHA-1").digest(input);
for (byte b : hash) {
formatter.format("%02x", b);
}
return formatter.toString();
} catch (Exception e) {
return null;
}
}
}

View File

@ -0,0 +1,32 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.common.protocoltranslator.provider;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import net.raphimc.vialegacy.protocol.release.r1_6_4tor1_7_2_5.provider.EncryptionProvider;
public class ViaForgeEncryptionProvider extends EncryptionProvider {
@Override
public void enableDecryption(UserConnection user) {
user.getChannel().attr(ViaForgeCommon.VF_NETWORK_MANAGER).getAndRemove().viaForge$setupPreNettyDecryption();
}
}

View File

@ -0,0 +1,31 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.common.protocoltranslator.provider;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.v1_8to1_9.provider.MovementTransmitterProvider;
public class ViaForgeMovementTransmitterProvider extends MovementTransmitterProvider {
@Override
public void sendPlayer(UserConnection userConnection) {
// We are on the client side, so we can handle the idle packet properly
}
}

View File

@ -0,0 +1,36 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.common.protocoltranslator.provider;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import net.raphimc.vialegacy.protocol.release.r1_2_4_5tor1_3_1_2.provider.OldAuthProvider;
public class ViaForgeOldAuthProvider extends OldAuthProvider {
@Override
public void sendAuthRequest(UserConnection user, String serverId) throws Throwable {
final ViaForgeCommon common = ViaForgeCommon.getManager();
if (!common.getConfig().isVerifySessionInOldVersions()) {
return;
}
common.getPlatform().joinServer(serverId);
}
}

View File

@ -0,0 +1,36 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.common.protocoltranslator.provider;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.protocol.version.BaseVersionProvider;
import de.florianmichael.viaforge.common.ViaForgeCommon;
public class ViaForgeVersionProvider extends BaseVersionProvider {
@Override
public ProtocolVersion getClosestServerProtocol(UserConnection connection) throws Exception {
if (connection.isClientSide() && !ViaForgeCommon.getManager().getPlatform().isSingleplayer().get()) {
return connection.getChannel().attr(ViaForgeCommon.VF_NETWORK_MANAGER).get().viaForge$getTrackedVersion();
}
return super.getClosestServerProtocol(connection);
}
}

View File

@ -0,0 +1,46 @@
# Thanks for downloading ViaForge!
# If you need help, you can join our Discord - https://viaversion.com/discord
#
# Disclaimer:
# It cannot be guaranteed that this mod is allowed on specific servers as it can possibly cause problems with anti-cheat plugins
# (USE ONLY WITH CAUTION!)
#
#----------------------------------------------------------#
# GLOBAL OPTIONS #
#----------------------------------------------------------#
#
# This option sets the protocol version to be used when connecting to servers. (can also be changed in-game)
client-side-version: -1
#
# Manually sends the joinServer request when connecting to <= 1.2.5 servers.
verify-session-in-old-versions: true
#
# Allow ViaForge to authenticate with BetaCraft's MP-Pass system for <= c0.30 servers.
allow-betacraft-authentication: true
#
# If enabled, ViaForge will show the current protocol version in the F3 menu.
show-protocol-version-in-f3: true
#
#----------------------------------------------------------#
# GUI OPTIONS #
#----------------------------------------------------------#
#
# This option indicates if the ViaForge button should be shown in the main menu.
show-main-menu-button: true
#
# This option indicates if the ViaForge button should be shown in the multiplayer.
show-multiplayer-button: true
#
# This option indicates if the ViaForge button should be shown in the direct connect screen.
show-direct-connect-button: true
#
# This option indicates if the ViaForge set version button should be shown in the server list.
show-add-server-button: true
#
# This option indicates where the ViaForge button should be located in all screens.
# Possible options: TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT
via-forge-button-position: "TOP_LEFT"
#
# This option indicates where the ViaForge set version button should be located in the add server screen.
# Possible options: TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT
add-server-screen-button-position: "TOP_LEFT"

BIN
src/main/resources/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -0,0 +1,7 @@
minecraft {
mappings channel: "stable", version: "39-1.12"
}
dependencies {
minecraft "net.minecraftforge:forge:1.12.2-14.23.5.2859"
}

View File

@ -0,0 +1,2 @@
maven_name=viaforge-mc1122
mc_version=1.12.2

View File

@ -0,0 +1,69 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.VFPlatform;
import de.florianmichael.viaforge.provider.ViaForgeGameProfileFetcher;
import net.minecraft.client.Minecraft;
import net.minecraft.realms.RealmsSharedConstants;
import net.minecraft.util.Session;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.provider.GameProfileFetcher;
import java.io.File;
import java.util.function.Supplier;
@Mod(modid = "viaforge", name = "ViaForge", acceptableRemoteVersions = "*", clientSideOnly=true, useMetadata=true)
public class ViaForge1122 implements VFPlatform {
@Mod.EventHandler
public void onInit(FMLInitializationEvent event) {
ViaForgeCommon.init(this);
}
@Override
public int getGameVersion() {
return RealmsSharedConstants.NETWORK_PROTOCOL_VERSION;
}
@Override
public Supplier<Boolean> isSingleplayer() {
return () -> Minecraft.getMinecraft().isSingleplayer();
}
@Override
public File getLeadingDirectory() {
return Minecraft.getMinecraft().gameDir;
}
@Override
public void joinServer(String serverId) throws Throwable {
final Session session = Minecraft.getMinecraft().getSession();
Minecraft.getMinecraft().getSessionService().joinServer(session.getProfile(), session.getToken(), serverId);
}
@Override
public GameProfileFetcher getGameProfileFetcher() {
return new ViaForgeGameProfileFetcher();
}
}

View File

@ -0,0 +1,176 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.gui;
import com.mojang.realmsclient.gui.ChatFormatting;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.util.DumpUtil;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiSlot;
import net.raphimc.vialoader.util.ProtocolVersionList;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
public class GuiProtocolSelector extends GuiScreen {
private final GuiScreen parent;
private final boolean simple;
private final FinishedCallback finishedCallback;
private SlotList list;
private String status;
private long time;
public GuiProtocolSelector(final GuiScreen parent) {
this(parent, false, (version, unused) -> {
// Default action is to set the target version and go back to the parent screen.
ViaForgeCommon.getManager().setTargetVersion(version);
});
}
public GuiProtocolSelector(final GuiScreen parent, final boolean simple, final FinishedCallback finishedCallback) {
this.parent = parent;
this.simple = simple;
this.finishedCallback = finishedCallback;
}
@Override
public void initGui() {
super.initGui();
buttonList.add(new GuiButton(1, 5, height - 25, 20, 20, "<-"));
if (!this.simple) {
buttonList.add(new GuiButton(2, width - 105, 5, 100, 20, "Create dump"));
buttonList.add(new GuiButton(3, width - 105, height - 25, 100, 20, "Reload configs"));
}
list = new SlotList(mc, width, height, 3 + 3 /* start offset */ + (fontRenderer.FONT_HEIGHT + 2) * 3 /* title is 2 */, height - 30, fontRenderer.FONT_HEIGHT + 2);
}
public void setStatus(final String status) {
this.status = status;
this.time = System.currentTimeMillis();
}
@Override
protected void actionPerformed(GuiButton button) {
list.actionPerformed(button);
if (button.id == 1) {
mc.displayGuiScreen(parent);
} else if (button.id == 2) {
try {
GuiScreen.setClipboardString(DumpUtil.postDump(UUID.randomUUID()).get());
setStatus(ChatFormatting.GREEN + "Dump created and copied to clipboard");
} catch (InterruptedException | ExecutionException e) {
setStatus(ChatFormatting.RED + "Failed to create dump: " + e.getMessage());
}
} else {
Via.getManager().getConfigurationProvider().reloadConfigs();
}
}
@Override
protected void keyTyped(char typedChar, int keyCode) {
if (keyCode == Keyboard.KEY_ESCAPE) {
mc.displayGuiScreen(parent);
}
}
@Override
public void handleMouseInput() throws IOException {
list.handleMouseInput();
super.handleMouseInput();
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
if (System.currentTimeMillis() - this.time >= 10_000) {
this.status = null;
}
list.drawScreen(mouseX, mouseY, partialTicks);
GL11.glPushMatrix();
GL11.glScalef(2.0F, 2.0F, 2.0F);
drawCenteredString(fontRenderer, ChatFormatting.GOLD + "ViaForge", width / 4, 3, 16777215);
GL11.glPopMatrix();
drawCenteredString(fontRenderer, "https://github.com/ViaVersion/ViaForge", width / 2, (fontRenderer.FONT_HEIGHT + 2) * 2 + 3, -1);
drawString(fontRenderer, status != null ? status : "Discord: florianmichael", 3, 3, -1);
super.drawScreen(mouseX, mouseY, partialTicks);
}
class SlotList extends GuiSlot {
public SlotList(Minecraft client, int width, int height, int top, int bottom, int slotHeight) {
super(client, width, height, top, bottom, slotHeight);
}
@Override
protected int getSize() {
return ProtocolVersionList.getProtocolsNewToOld().size();
}
@Override
protected void elementClicked(int index, boolean b, int i1, int i2) {
finishedCallback.finished(ProtocolVersionList.getProtocolsNewToOld().get(index), parent);
}
@Override
protected boolean isSelected(int index) {
return false;
}
@Override
protected void drawBackground() {
drawDefaultBackground();
}
@Override
protected void drawSlot(int index, int x, int y, int slotHeight, int mouseX, int mouseY, float partialTicks) {
final ProtocolVersion targetVersion = ViaForgeCommon.getManager().getTargetVersion();
final ProtocolVersion version = ProtocolVersionList.getProtocolsNewToOld().get(index);
String color;
if (targetVersion == version) {
color = GuiProtocolSelector.this.simple ? ChatFormatting.GOLD.toString() : ChatFormatting.GREEN.toString();
} else {
color = GuiProtocolSelector.this.simple ? ChatFormatting.WHITE.toString() : ChatFormatting.DARK_RED.toString();
}
drawCenteredString(mc.fontRenderer,(color) + version.getName(), width / 2, y, -1);
}
}
public interface FinishedCallback {
void finished(final ProtocolVersion version, final GuiScreen parent);
}
}

View File

@ -1,6 +1,6 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,6 +15,7 @@
* 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.viaforge.mixin;
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
@ -27,9 +28,8 @@ import java.util.Map;
public class MixinLoader implements IFMLLoadingPlugin {
public MixinLoader() {
System.out.println("Starting MixinBootstrap from IFMLLoadingPlugin");
MixinBootstrap.init();
Mixins.addConfiguration("mixins.viaforge.json");
Mixins.addConfiguration("mixins.viaforge-mc1122.json");
MixinEnvironment.getDefaultEnvironment().setSide(MixinEnvironment.Side.CLIENT);
}
@ -49,10 +49,12 @@ public class MixinLoader implements IFMLLoadingPlugin {
}
@Override
public void injectData(Map<String, Object> data) { }
public void injectData(Map<String, Object> data) {
}
@Override
public String getAccessTransformerClass() {
return null;
}
}

View File

@ -0,0 +1,55 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.impl;
import com.viaversion.viaversion.util.Pair;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.ViaForgeConfig;
import de.florianmichael.viaforge.gui.GuiProtocolSelector;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiMainMenu;
import net.minecraft.client.gui.GuiScreen;
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(GuiMainMenu.class)
public class MixinGuiMainMenu extends GuiScreen {
@Inject(method = "initGui", at = @At("RETURN"))
public void hookViaForgeButton(CallbackInfo ci) {
final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig();
if (config.isShowMainMenuButton()) {
final Pair<Integer, Integer> pos = config.getViaForgeButtonPosition().getPosition(this.width, this.height);
buttonList.add(new GuiButton(1_000_000_000, pos.key(), pos.value(), 100, 20, "ViaForge"));
}
}
@Inject(method = "actionPerformed", at = @At("RETURN"))
public void handleViaForgeButtonClicking(GuiButton p_actionPerformed_1_, CallbackInfo ci) {
if (ViaForgeCommon.getManager().getConfig().isShowMainMenuButton()) {
if (p_actionPerformed_1_.id == 1_000_000_000) {
mc.displayGuiScreen(new GuiProtocolSelector(this));
}
}
}
}

View File

@ -1,6 +1,6 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,8 +15,12 @@
* 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.viaforge.mixin.impl;
import com.viaversion.viaversion.util.Pair;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.ViaForgeConfig;
import de.florianmichael.viaforge.gui.GuiProtocolSelector;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiMultiplayer;
@ -30,14 +34,22 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
public class MixinGuiMultiplayer extends GuiScreen {
@Inject(method = "initGui", at = @At("RETURN"))
public void hookCustomButton(CallbackInfo ci) {
buttonList.add(new GuiButton(1337, 5, 6, 98, 20, "ViaForge"));
public void hookViaForgeButton(CallbackInfo ci) {
final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig();
if (config.isShowMultiplayerButton()) {
final Pair<Integer, Integer> pos = config.getViaForgeButtonPosition().getPosition(this.width, this.height);
buttonList.add(new GuiButton(1_000_000_000, pos.key(), pos.value(), 100, 20, "ViaForge"));
}
}
@Inject(method = "actionPerformed", at = @At("RETURN"))
public void handleCustomButtonAction(GuiButton p_actionPerformed_1_, CallbackInfo ci) {
if (p_actionPerformed_1_.id == 1337) {
mc.displayGuiScreen(new GuiProtocolSelector(this));
public void handleViaForgeButtonClicking(GuiButton p_actionPerformed_1_, CallbackInfo ci) {
if (ViaForgeCommon.getManager().getConfig().isShowMultiplayerButton()) {
if (p_actionPerformed_1_.id == 1_000_000_000) {
mc.displayGuiScreen(new GuiProtocolSelector(this));
}
}
}
}

View File

@ -0,0 +1,45 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.impl;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import net.minecraft.client.gui.GuiOverlayDebug;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@Mixin(GuiOverlayDebug.class)
public class MixinGuiOverlayDebug {
@Inject(method = "getDebugInfoRight", at = @At(value = "TAIL"))
public void addViaForgeVersion(CallbackInfoReturnable<List<String>> cir) {
final ViaForgeCommon common = ViaForgeCommon.getManager();
final ProtocolVersion version = ViaForgeCommon.getManager().getTargetVersion();
if (common.getConfig().isShowProtocolVersionInF3() && version != common.getNativeVersion() && !common.getPlatform().isSingleplayer().get()) {
cir.getReturnValue().add("");
cir.getReturnValue().add("ViaForge: " + version.toString());
}
}
}

View File

@ -0,0 +1,68 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.impl;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.util.Pair;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.gui.ExtendedServerData;
import de.florianmichael.viaforge.common.platform.ViaForgeConfig;
import de.florianmichael.viaforge.gui.GuiProtocolSelector;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiScreenAddServer;
import net.minecraft.client.multiplayer.ServerData;
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.callback.CallbackInfo;
@Mixin(GuiScreenAddServer.class)
public class MixinGuiScreenAddServer extends GuiScreen {
@Shadow @Final private ServerData serverData;
@Inject(method = "initGui", at = @At("RETURN"))
public void initGui(CallbackInfo ci) {
final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig();
if (config.isShowAddServerButton()) {
final Pair<Integer, Integer> pos = config.getAddServerScreenButtonPosition().getPosition(this.width, this.height);
final ProtocolVersion target = ((ExtendedServerData) serverData).viaForge$getVersion();
buttonList.add(new GuiButton(1_000_000_000, pos.key(), pos.value(), 100, 20, target != null ? target.getName() : "Set Version"));
}
}
@Inject(method = "actionPerformed", at = @At("HEAD"))
public void actionPerformed(GuiButton button, CallbackInfo ci) {
if (ViaForgeCommon.getManager().getConfig().isShowAddServerButton()) {
if (button.id == 1_000_000_000) {
mc.displayGuiScreen(new GuiProtocolSelector(this, true, (version, parent) -> {
// Set version and go back to the parent screen.
((ExtendedServerData) serverData).viaForge$setVersion(version);
mc.displayGuiScreen(parent);
}));
}
}
}
}

View File

@ -1,6 +1,6 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,8 +15,12 @@
* 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.viaforge.mixin.impl;
import com.viaversion.viaversion.util.Pair;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.ViaForgeConfig;
import de.florianmichael.viaforge.gui.GuiProtocolSelector;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
@ -30,14 +34,22 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
public class MixinGuiScreenServerList extends GuiScreen {
@Inject(method = "initGui", at = @At("RETURN"))
public void hookCustomButton(CallbackInfo ci) {
buttonList.add(new GuiButton(1337, 5, 6, 98, 20, "ViaForge"));
public void hookViaForgeButton(CallbackInfo ci) {
final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig();
if (config.isShowDirectConnectButton()) {
final Pair<Integer, Integer> pos = config.getViaForgeButtonPosition().getPosition(this.width, this.height);
buttonList.add(new GuiButton(1_000_000_000, pos.key(), pos.value(), 100, 20, "ViaForge"));
}
}
@Inject(method = "actionPerformed", at = @At("RETURN"))
public void handleCustomButtonAction(GuiButton p_actionPerformed_1_, CallbackInfo ci) {
if (p_actionPerformed_1_.id == 1337) {
mc.displayGuiScreen(new GuiProtocolSelector(this));
public void handleViaForgeButtonClicking(GuiButton p_actionPerformed_1_, CallbackInfo ci) {
if (ViaForgeCommon.getManager().getConfig().isShowDirectConnectButton()) {
if (p_actionPerformed_1_.id == 1_000_000_000) {
mc.displayGuiScreen(new GuiProtocolSelector(this));
}
}
}
}

View File

@ -0,0 +1,70 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.impl;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viaforge.common.gui.ExtendedServerData;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.nbt.NBTTagCompound;
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.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(ServerData.class)
public class MixinServerData implements ExtendedServerData {
@Unique
private ProtocolVersion viaForge$version;
@Inject(method = "getNBTCompound", at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/NBTTagCompound;setString(Ljava/lang/String;Ljava/lang/String;)V", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD)
public void saveVersion(CallbackInfoReturnable<NBTTagCompound> cir, NBTTagCompound nbttagcompound) {
if (viaForge$version != null) {
nbttagcompound.setString("viaForge$version", viaForge$version.getName());
}
}
@Inject(method = "getServerDataFromNBTCompound", at = @At(value = "TAIL"))
private static void getVersion(NBTTagCompound nbtCompound, CallbackInfoReturnable<ServerData> cir) {
if (nbtCompound.hasKey("viaForge$version")) {
((ExtendedServerData) cir.getReturnValue()).viaForge$setVersion(ProtocolVersion.getClosest(nbtCompound.getString("viaForge$version")));
}
}
@Inject(method = "copyFrom", at = @At("HEAD"))
public void track(ServerData serverDataIn, CallbackInfo ci) {
if (serverDataIn instanceof ExtendedServerData) {
viaForge$version = ((ExtendedServerData) serverDataIn).viaForge$getVersion();
}
}
@Override
public ProtocolVersion viaForge$getVersion() {
return viaForge$version;
}
@Override
public void viaForge$setVersion(ProtocolVersion version) {
viaForge$version = version;
}
}

View File

@ -0,0 +1,47 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.impl.connect;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.gui.ExtendedServerData;
import de.florianmichael.viaforge.common.platform.VersionTracker;
import net.minecraft.client.Minecraft;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Mixin(targets = "net.minecraft.client.multiplayer.GuiConnecting$1")
public class MixinGuiConnecting_1 {
@Redirect(method = "run", at = @At(value = "INVOKE", target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;"))
public InetAddress trackServerVersion(String s) throws UnknownHostException {
final InetAddress address = InetAddress.getByName(s);
ProtocolVersion version = ((ExtendedServerData) Minecraft.getMinecraft().getCurrentServerData()).viaForge$getVersion();
if (version == null) {
version = ViaForgeCommon.getManager().getTargetVersion();
}
VersionTracker.storeServerProtocolVersion(address, version);
return address;
}
}

View File

@ -0,0 +1,58 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.impl.connect;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.exceptions.AuthenticationException;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.protocoltranslator.netty.VFNetworkManager;
import net.minecraft.client.network.NetHandlerLoginClient;
import net.minecraft.network.NetworkManager;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
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;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@SuppressWarnings("DataFlowIssue")
@Mixin(NetHandlerLoginClient.class)
public class MixinNetHandlerLoginClient {
@Shadow @Final private NetworkManager networkManager;
@Redirect(method = "handleEncryptionRequest", at = @At(value = "INVOKE", target = "Lcom/mojang/authlib/minecraft/MinecraftSessionService;joinServer(Lcom/mojang/authlib/GameProfile;Ljava/lang/String;Ljava/lang/String;)V"))
public void onlyJoinServerIfPremium(MinecraftSessionService instance, GameProfile profile, String authenticationToken, String serverId) throws AuthenticationException {
final VFNetworkManager mixinNetworkManager = (VFNetworkManager) networkManager;
if (mixinNetworkManager.viaForge$getTrackedVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
final UserConnection user = networkManager.channel().attr(ViaForgeCommon.LOCAL_VIA_USER).get();
if (user != null && user.has(ProtocolMetadataStorage.class) && !user.get(ProtocolMetadataStorage.class).authenticate) {
// We are in the 1.7 -> 1.6 protocol, so we need to skip the joinServer call
// if the server is in offline mode, due the packet changes <-> networking changes
// Minecraft's networking code is bad for us.
return;
}
}
instance.joinServer(profile, authenticationToken, serverId);
}
}

View File

@ -0,0 +1,102 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.impl.connect;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.VersionTracker;
import de.florianmichael.viaforge.common.protocoltranslator.netty.VFNetworkManager;
import io.netty.channel.Channel;
import net.minecraft.network.NettyEncryptingDecoder;
import net.minecraft.network.NettyEncryptingEncoder;
import net.minecraft.network.NetworkManager;
import net.minecraft.util.CryptManager;
import net.minecraft.util.LazyLoadBase;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialoader.netty.VLLegacyPipeline;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import java.net.InetAddress;
@Mixin(NetworkManager.class)
public class MixinNetworkManager implements VFNetworkManager {
@Shadow private Channel channel;
@Shadow private boolean isEncrypted;
@Unique
private Cipher viaForge$decryptionCipher;
@Unique
private ProtocolVersion viaForge$targetVersion;
@Inject(method = "setCompressionThreshold", at = @At("RETURN"))
public void reorderPipeline(int p_setCompressionTreshold_1_, CallbackInfo ci) {
ViaForgeCommon.getManager().reorderCompression(channel);
}
@Inject(method = "enableEncryption", at = @At("HEAD"), cancellable = true)
private void storeEncryptionCiphers(SecretKey key, CallbackInfo ci) {
if (viaForge$targetVersion != null && viaForge$targetVersion.olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
// Minecraft's encryption code is bad for us, we need to reorder the pipeline
ci.cancel();
// Minecraft 1.6.4 supports tile encryption 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.
this.viaForge$decryptionCipher = CryptManager.createNetCipherInstance(2, key);
// Enabling the encryption side
this.isEncrypted = true;
this.channel.pipeline().addBefore(VLLegacyPipeline.VIALEGACY_PRE_NETTY_LENGTH_REMOVER_NAME, "encrypt", new NettyEncryptingEncoder(CryptManager.createNetCipherInstance(1, key)));
}
}
@Inject(method = "createNetworkManagerAndConnect", at = @At(value = "INVOKE", target = "Lio/netty/bootstrap/Bootstrap;group(Lio/netty/channel/EventLoopGroup;)Lio/netty/bootstrap/AbstractBootstrap;"), locals = LocalCapture.CAPTURE_FAILHARD)
private static void setTargetVersion(InetAddress address, int serverPort, boolean useNativeTransport, CallbackInfoReturnable<NetworkManager> cir, NetworkManager networkmanager, Class oclass, LazyLoadBase lazyloadbase) {
final VFNetworkManager mixinNetworkManager = (VFNetworkManager) networkmanager;
mixinNetworkManager.viaForge$setTrackedVersion(VersionTracker.getServerProtocolVersion(address));
}
@Override
public void viaForge$setupPreNettyDecryption() {
// 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_REMOVER_NAME, "decrypt", new NettyEncryptingDecoder(this.viaForge$decryptionCipher));
}
@Override
public ProtocolVersion viaForge$getTrackedVersion() {
return viaForge$targetVersion;
}
@Override
public void viaForge$setTrackedVersion(ProtocolVersion version) {
viaForge$targetVersion = version;
}
}

View File

@ -1,6 +1,6 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,16 +15,14 @@
* 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.viaforge.mixin.impl;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.connection.UserConnectionImpl;
import com.viaversion.viaversion.protocol.ProtocolPipelineImpl;
import de.florianmichael.viaforge.ViaForge;
import de.florianmichael.viaforge.ViaForgeVLLegacyPipeline;
package de.florianmichael.viaforge.mixin.impl.connect;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.protocoltranslator.netty.VFNetworkManager;
import io.netty.channel.Channel;
import io.netty.channel.socket.SocketChannel;
import org.spongepowered.asm.mixin.Mixin;
import net.minecraft.network.NetworkManager;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@ -32,13 +30,13 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(targets = "net.minecraft.network.NetworkManager$5")
public class MixinNetworkManager_5 {
@Inject(method = "initChannel", at = @At(value = "TAIL"), remap = false)
private void onInitChannel(Channel channel, CallbackInfo ci) {
if (channel instanceof SocketChannel && ViaForge.targetVersion != ViaForge.NATIVE_VERSION) {
final UserConnection user = new UserConnectionImpl(channel, true);
new ProtocolPipelineImpl(user);
@Final
@Mutable
NetworkManager val$networkmanager;
channel.pipeline().addLast(new ViaForgeVLLegacyPipeline(user, ViaForge.targetVersion));
}
@Inject(method = "initChannel", at = @At(value = "TAIL"), remap = false)
private void hookViaPipeline(Channel channel, CallbackInfo ci) {
ViaForgeCommon.getManager().inject(channel, (VFNetworkManager) val$networkmanager);
}
}

View File

@ -0,0 +1,60 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.impl.connect;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.gui.ExtendedServerData;
import de.florianmichael.viaforge.common.platform.VersionTracker;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.network.ServerPinger;
import net.minecraft.network.NetworkManager;
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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.net.InetAddress;
@Mixin(ServerPinger.class)
public class MixinServerPinger {
@Unique
private ServerData viaForge$serverData;
@Inject(method = "ping", at = @At("HEAD"))
public void trackServerData(ServerData server, CallbackInfo ci) {
viaForge$serverData = server;
}
@Redirect(method = "ping", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/NetworkManager;createNetworkManagerAndConnect(Ljava/net/InetAddress;IZ)Lnet/minecraft/network/NetworkManager;"))
public NetworkManager trackVersion(InetAddress address, int i, boolean b) {
ProtocolVersion version = ((ExtendedServerData) viaForge$serverData).viaForge$getVersion();
if (version == null) {
version = ViaForgeCommon.getManager().getTargetVersion();
}
VersionTracker.storeServerProtocolVersion(address, version);
viaForge$serverData = null;
return NetworkManager.createNetworkManagerAndConnect(address, i, b);
}
}

View File

@ -0,0 +1,56 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.impl.fixes;
import com.mojang.authlib.GameProfile;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import net.minecraft.client.entity.AbstractClientPlayer;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.world.World;
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(EntityPlayerSP.class)
public class MixinEntityPlayerSP extends AbstractClientPlayer {
@Shadow private boolean prevOnGround;
public MixinEntityPlayerSP(World worldIn, GameProfile playerProfile) {
super(worldIn, playerProfile);
}
@Redirect(method = "onUpdateWalkingPlayer", at = @At(value = "FIELD", target = "Lnet/minecraft/client/entity/EntityPlayerSP;prevOnGround:Z", ordinal = 0))
public boolean emulateIdlePacket(EntityPlayerSP instance) {
if (ViaForgeCommon.getManager().getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
// <= 1.8 spams the idle packet instead of only sending it when the ground state changes
// So we invert the original logic:
// if (prevOnGround != onGround) sendPacket
// To be like:
// if (!onGround != onGround) sendPacket
// Which is the same as:
// if (true) sendPacket
return !onGround;
}
return prevOnGround;
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.provider;
import com.mojang.authlib.Agent;
import com.mojang.authlib.GameProfileRepository;
import com.mojang.authlib.HttpAuthenticationService;
import com.mojang.authlib.ProfileLookupCallback;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.yggdrasil.ProfileNotFoundException;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.model.GameProfile;
import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.provider.GameProfileFetcher;
import java.net.Proxy;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class ViaForgeGameProfileFetcher extends GameProfileFetcher {
public static final HttpAuthenticationService AUTHENTICATION_SERVICE = new YggdrasilAuthenticationService(Proxy.NO_PROXY, "");
public static final MinecraftSessionService SESSION_SERVICE = AUTHENTICATION_SERVICE.createMinecraftSessionService();
public static final GameProfileRepository GAME_PROFILE_REPOSITORY = AUTHENTICATION_SERVICE.createProfileRepository();
@Override
public UUID loadMojangUUID(String playerName) throws Exception {
final CompletableFuture<com.mojang.authlib.GameProfile> future = new CompletableFuture<>();
GAME_PROFILE_REPOSITORY.findProfilesByNames(new String[]{playerName}, Agent.MINECRAFT, new ProfileLookupCallback() {
@Override
public void onProfileLookupSucceeded(com.mojang.authlib.GameProfile profile) {
future.complete(profile);
}
@Override
public void onProfileLookupFailed(com.mojang.authlib.GameProfile profile, Exception exception) {
future.completeExceptionally(exception);
}
});
if (!future.isDone()) {
future.completeExceptionally(new ProfileNotFoundException());
}
return future.get().getId();
}
@Override
public GameProfile loadGameProfile(UUID uuid) {
final com.mojang.authlib.GameProfile inProfile = new com.mojang.authlib.GameProfile(uuid, null);
final com.mojang.authlib.GameProfile mojangProfile = SESSION_SERVICE.fillProfileProperties(inProfile, true);
if (mojangProfile.equals(inProfile)) throw new ProfileNotFoundException();
final GameProfile gameProfile = new GameProfile(mojangProfile.getName(), mojangProfile.getId());
for (final java.util.Map.Entry<String, Property> entry : mojangProfile.getProperties().entries()) {
final Property prop = entry.getValue();
gameProfile.addProperty(new GameProfile.Property(prop.getName(), prop.getValue(), prop.getSignature()));
}
return gameProfile;
}
}

View File

@ -0,0 +1,15 @@
[
{
"modid": "viaforge",
"name": "ViaForge",
"description": "Client-side Implementation of the Via* projects for Minecraft Forge",
"version": "${version}",
"mcversion": "[1.12,)",
"url": "https://github.com/ViaVersion/ViaForge",
"authorList": [
"FlorianMichael/EnZaXD"
],
"credits": "https://github.com/FlorianMichael/",
"logoFile": "icon.png"
}
]

View File

@ -0,0 +1,22 @@
{
"required": true,
"minVersion": "0.7.5",
"compatibilityLevel": "JAVA_8",
"package": "de.florianmichael.viaforge.mixin.impl",
"refmap": "mixins.viaforge-mc1122.refmap.json",
"client": [
"connect.MixinGuiConnecting_1",
"MixinGuiMainMenu",
"MixinGuiMultiplayer",
"MixinGuiOverlayDebug",
"MixinGuiScreenAddServer",
"MixinGuiScreenServerList",
"connect.MixinNetHandlerLoginClient",
"connect.MixinNetworkManager",
"connect.MixinNetworkManager_5",
"MixinServerData",
"connect.MixinServerPinger",
"fixes.MixinEntityPlayerSP"
],
"verbose": true
}

View File

@ -0,0 +1,7 @@
minecraft {
mappings channel: "official", version: "1.16.5"
}
dependencies {
minecraft "net.minecraftforge:forge:1.16.5-36.2.39"
}

View File

@ -0,0 +1,2 @@
maven_name=viaforge-mc1165
mc_version=1.16.5

View File

@ -0,0 +1,73 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.VFPlatform;
import de.florianmichael.viaforge.provider.ViaForgeGameProfileFetcher;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Session;
import net.minecraft.util.SharedConstants;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.provider.GameProfileFetcher;
import java.io.File;
import java.util.function.Supplier;
@Mod("viaforge")
public class ViaForge1165 implements VFPlatform {
public ViaForge1165() {
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onInit);
}
public void onInit(FMLCommonSetupEvent event) {
ViaForgeCommon.init(this);
}
@Override
public int getGameVersion() {
return SharedConstants.getProtocolVersion();
}
@Override
public Supplier<Boolean> isSingleplayer() {
return () -> Minecraft.getInstance().hasSingleplayerServer();
}
@Override
public File getLeadingDirectory() {
return Minecraft.getInstance().gameDirectory;
}
@Override
public void joinServer(String serverId) throws Throwable {
final Session session = Minecraft.getInstance().getUser();
Minecraft.getInstance().getMinecraftSessionService().joinServer(session.getGameProfile(), session.getAccessToken(), serverId);
}
@Override
public GameProfileFetcher getGameProfileFetcher() {
return new ViaForgeGameProfileFetcher();
}
}

View File

@ -0,0 +1,167 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.gui;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.util.DumpUtil;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.gui.widget.list.AbstractList;
import net.minecraft.client.gui.widget.list.ExtendedList;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.raphimc.vialoader.util.ProtocolVersionList;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL11;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
public class GuiProtocolSelector extends Screen {
public final Screen parent;
public final boolean simple;
public final FinishedCallback finishedCallback;
private SlotList list;
private String status;
private long time;
public static void open(final Minecraft minecraft) { // Bypass for some weird bytecode instructions errors in Forge
minecraft.setScreen(new GuiProtocolSelector(minecraft.screen));
}
public GuiProtocolSelector(final Screen parent) {
this(parent, false, (version, unused) -> {
// Default action is to set the target version and go back to the parent screen.
ViaForgeCommon.getManager().setTargetVersion(version);
});
}
public GuiProtocolSelector(final Screen parent, final boolean simple, final FinishedCallback finishedCallback) {
super(new StringTextComponent("ViaForge Protocol Selector"));
this.parent = parent;
this.simple = simple;
this.finishedCallback = finishedCallback;
}
@Override
public void init() {
super.init();
addButton(new Button(5, height - 25, 20, 20, new StringTextComponent("<-"), b -> minecraft.setScreen(parent)));
if (!this.simple) {
addButton(new Button(width - 105, 5, 100, 20, new StringTextComponent("Create dump"), b -> {
try {
minecraft.keyboardHandler.setClipboard(DumpUtil.postDump(UUID.randomUUID()).get());
setStatus(TextFormatting.GREEN + "Dump created and copied to clipboard");
} catch (InterruptedException | ExecutionException e) {
setStatus(TextFormatting.RED + "Failed to create dump: " + e.getMessage());
}
}));
addButton(new Button(width - 105, height - 25, 100, 20, new StringTextComponent("Reload configs"), b -> Via.getManager().getConfigurationProvider().reloadConfigs()));
}
addWidget(list = new SlotList(minecraft, width, height, 3 + 3 /* start offset */ + (font.lineHeight + 2) * 3 /* title is 2 */, height - 30, font.lineHeight + 2));
}
public void setStatus(final String status) {
this.status = status;
this.time = System.currentTimeMillis();
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int actions) {
if (keyCode == GLFW.GLFW_KEY_ESCAPE) {
minecraft.setScreen(parent);
}
return super.keyPressed(keyCode, scanCode, actions);
}
@Override
public void render(MatrixStack matrices, int p_230430_2_, int p_230430_3_, float p_230430_4_) {
if (System.currentTimeMillis() - this.time >= 10_000) {
this.status = null;
}
renderBackground(matrices);
list.render(matrices, p_230430_2_, p_230430_3_, p_230430_4_);
super.render(matrices, p_230430_2_, p_230430_3_, p_230430_4_);
GL11.glPushMatrix();
GL11.glScalef(2.0F, 2.0F, 2.0F);
drawCenteredString(matrices, font, TextFormatting.GOLD + "ViaForge", width / 4, 3, 16777215);
GL11.glPopMatrix();
drawCenteredString(matrices, font, "https://github.com/ViaVersion/ViaForge", width / 2, (font.lineHeight + 2) * 2 + 3, -1);
drawString(matrices, font, status != null ? status : "Discord: florianmichael", 3, 3, -1);
}
class SlotList extends ExtendedList<SlotList.SlotEntry> {
public SlotList(Minecraft client, int width, int height, int top, int bottom, int slotHeight) {
super(client, width, height, top, bottom, slotHeight);
for (ProtocolVersion version : ProtocolVersionList.getProtocolsNewToOld()) {
addEntry(new SlotEntry(version));
}
}
public class SlotEntry extends AbstractList.AbstractListEntry<SlotEntry> {
private final ProtocolVersion ProtocolVersion;
public SlotEntry(ProtocolVersion ProtocolVersion) {
this.ProtocolVersion = ProtocolVersion;
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
GuiProtocolSelector.this.finishedCallback.finished(ProtocolVersion, GuiProtocolSelector.this.parent);
return super.mouseClicked(mouseX, mouseY, button);
}
@Override
public void render(MatrixStack matrices, int p_230432_2_, int y, int p_230432_4_, int p_230432_5_, int p_230432_6_, int p_230432_7_, int p_230432_8_, boolean p_230432_9_, float p_230432_10_) {
final ProtocolVersion targetVersion = ViaForgeCommon.getManager().getTargetVersion();
String color;
if (targetVersion == ProtocolVersion) {
color = GuiProtocolSelector.this.simple ? TextFormatting.GOLD.toString() : TextFormatting.GREEN.toString();
} else {
color = GuiProtocolSelector.this.simple ? TextFormatting.WHITE.toString() : TextFormatting.DARK_RED.toString();
}
drawCenteredString(matrices, Minecraft.getInstance().font, color + ProtocolVersion.getName(), width / 2, y, -1);
}
}
}
public interface FinishedCallback {
void finished(final ProtocolVersion version, final Screen parent);
}
}

View File

@ -0,0 +1,67 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin;
import com.viaversion.viaversion.util.Pair;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.gui.ExtendedServerData;
import de.florianmichael.viaforge.common.platform.ViaForgeConfig;
import de.florianmichael.viaforge.gui.GuiProtocolSelector;
import net.minecraft.client.gui.screen.AddServerScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
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.callback.CallbackInfo;
@Mixin(AddServerScreen.class)
public class MixinAddServerScreen extends Screen {
@Shadow @Final private ServerData serverData;
public MixinAddServerScreen(ITextComponent title) {
super(title);
}
@Inject(method = "init", at = @At("RETURN"))
public void initGui(CallbackInfo ci) {
final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig();
if (config.isShowAddServerButton()) {
final Pair<Integer, Integer> pos = config.getAddServerScreenButtonPosition().getPosition(this.width, this.height);
final ProtocolVersion target = ((ExtendedServerData) serverData).viaForge$getVersion();
addButton(new Button(pos.key(), pos.value(), 100, 20, new StringTextComponent(target != null ? target.getName() : "Set Version"), b -> {
minecraft.setScreen(new GuiProtocolSelector(this, true, (version, parent) -> {
// Set version and go back to the parent screen.
((ExtendedServerData) serverData).viaForge$setVersion(version);
minecraft.setScreen(parent);
}));
}));
}
}
}

View File

@ -0,0 +1,45 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import net.minecraft.client.gui.overlay.DebugOverlayGui;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@Mixin(DebugOverlayGui.class)
public class MixinDebugOverlayGui {
@Inject(method = "getSystemInformation", at = @At(value = "TAIL"))
public void addViaForgeVersion(CallbackInfoReturnable<List<String>> cir) {
final ViaForgeCommon common = ViaForgeCommon.getManager();
final ProtocolVersion version = ViaForgeCommon.getManager().getTargetVersion();
if (common.getConfig().isShowProtocolVersionInF3() && version != common.getNativeVersion() && !common.getPlatform().isSingleplayer().get()) {
cir.getReturnValue().add("");
cir.getReturnValue().add("ViaForge: " + version.toString());
}
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin;
import com.viaversion.viaversion.util.Pair;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.ViaForgeConfig;
import de.florianmichael.viaforge.gui.GuiProtocolSelector;
import net.minecraft.client.gui.screen.MainMenuScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
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(MainMenuScreen.class)
public class MixinMainMenuScreen extends Screen {
public MixinMainMenuScreen(ITextComponent title) {
super(title);
}
@Inject(method = "init", at = @At("RETURN"))
public void hookViaForgeButton(CallbackInfo ci) {
final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig();
if (config.isShowMainMenuButton()) {
final Pair<Integer, Integer> pos = config.getViaForgeButtonPosition().getPosition(this.width, this.height);
addButton(new Button(pos.key(), pos.value(), 100, 20, new StringTextComponent("ViaForge"), buttons -> GuiProtocolSelector.open(minecraft)));
}
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin;
import com.viaversion.viaversion.util.Pair;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.ViaForgeConfig;
import de.florianmichael.viaforge.gui.GuiProtocolSelector;
import net.minecraft.client.gui.screen.MultiplayerScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
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(MultiplayerScreen.class)
public class MixinMultiplayerScreen extends Screen {
public MixinMultiplayerScreen(ITextComponent title) {
super(title);
}
@Inject(method = "init", at = @At("RETURN"))
public void hookViaForgeButton(CallbackInfo ci) {
final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig();
if (config.isShowMainMenuButton()) {
final Pair<Integer, Integer> pos = config.getViaForgeButtonPosition().getPosition(this.width, this.height);
addButton(new Button(pos.key(), pos.value(), 100, 20, new StringTextComponent("ViaForge"), buttons -> GuiProtocolSelector.open(minecraft)));
}
}
}

View File

@ -0,0 +1,70 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin;
import de.florianmichael.viaforge.common.gui.ExtendedServerData;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.nbt.CompoundNBT;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
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.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(ServerData.class)
public class MixinServerData implements ExtendedServerData {
@Unique
private ProtocolVersion viaForge$version;
@Inject(method = "write", at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/CompoundNBT;putString(Ljava/lang/String;Ljava/lang/String;)V", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD)
public void saveVersion(CallbackInfoReturnable<CompoundNBT> cir, CompoundNBT compoundnbt) {
if (viaForge$version != null) {
compoundnbt.putString("viaForge$version", viaForge$version.getName());
}
}
@Inject(method = "read", at = @At(value = "TAIL"))
private static void getVersion(CompoundNBT compoundnbt, CallbackInfoReturnable<ServerData> cir) {
if (compoundnbt.contains("viaForge$version")) {
((ExtendedServerData) cir.getReturnValue()).viaForge$setVersion(ProtocolVersion.getClosest(compoundnbt.getString("viaForge$version")));
}
}
@Inject(method = "copyFrom", at = @At("HEAD"))
public void track(ServerData serverDataIn, CallbackInfo ci) {
if (serverDataIn instanceof ExtendedServerData) {
viaForge$version = ((ExtendedServerData) serverDataIn).viaForge$getVersion();
}
}
@Override
public ProtocolVersion viaForge$getVersion() {
return viaForge$version;
}
@Override
public void viaForge$setVersion(ProtocolVersion version) {
viaForge$version = version;
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin;
import com.viaversion.viaversion.util.Pair;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.ViaForgeConfig;
import de.florianmichael.viaforge.gui.GuiProtocolSelector;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ServerListScreen;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
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(ServerListScreen.class)
public class MixinServerListScreen extends Screen {
public MixinServerListScreen(ITextComponent title) {
super(title);
}
@Inject(method = "init", at = @At("RETURN"))
public void hookViaForgeButton(CallbackInfo ci) {
final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig();
if (config.isShowDirectConnectButton()) {
final Pair<Integer, Integer> pos = config.getViaForgeButtonPosition().getPosition(this.width, this.height);
addButton(new Button(pos.key(), pos.value(), 100, 20, new StringTextComponent("ViaForge"), b -> GuiProtocolSelector.open(minecraft)));
}
}
}

View File

@ -0,0 +1,58 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.connect;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.exceptions.AuthenticationException;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.protocoltranslator.netty.VFNetworkManager;
import net.minecraft.client.network.login.ClientLoginNetHandler;
import net.minecraft.network.NetworkManager;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
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;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@SuppressWarnings("DataFlowIssue")
@Mixin(ClientLoginNetHandler.class)
public class MixinClientLoginNetHandler {
@Shadow @Final private NetworkManager connection;
@Redirect(method = "authenticateServer", at = @At(value = "INVOKE", target = "Lcom/mojang/authlib/minecraft/MinecraftSessionService;joinServer(Lcom/mojang/authlib/GameProfile;Ljava/lang/String;Ljava/lang/String;)V"))
public void onlyJoinServerIfPremium(MinecraftSessionService instance, GameProfile profile, String authenticationToken, String serverId) throws AuthenticationException {
final VFNetworkManager mixinConnection = (VFNetworkManager) connection;
if (mixinConnection.viaForge$getTrackedVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
final UserConnection user = connection.channel().attr(ViaForgeCommon.LOCAL_VIA_USER).get();
if (user != null && user.has(ProtocolMetadataStorage.class) && !user.get(ProtocolMetadataStorage.class).authenticate) {
// We are in the 1.7 -> 1.6 protocol, so we need to skip the joinServer call
// if the server is in offline mode, due the packet changes <-> networking changes
// Minecraft's networking code is bad for us.
return;
}
}
instance.joinServer(profile, authenticationToken, serverId);
}
}

View File

@ -0,0 +1,48 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.connect;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.gui.ExtendedServerData;
import de.florianmichael.viaforge.common.platform.VersionTracker;
import net.minecraft.client.Minecraft;
import net.minecraft.network.NetworkManager;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.net.InetAddress;
import java.net.UnknownHostException;
@Mixin(targets = "net.minecraft.client.gui.screen.ConnectingScreen$1")
public class MixinConnectingScreen_1 {
@Redirect(method = "run", at = @At(value = "INVOKE", target = "Ljava/net/InetAddress;getByName(Ljava/lang/String;)Ljava/net/InetAddress;"))
public InetAddress trackServerVersion(String s) throws UnknownHostException {
final InetAddress address = InetAddress.getByName(s);
ProtocolVersion version = ((ExtendedServerData) Minecraft.getInstance().getCurrentServer()).viaForge$getVersion();
if (version == null) {
version = ViaForgeCommon.getManager().getTargetVersion();
}
VersionTracker.storeServerProtocolVersion(address, version);
return address;
}
}

View File

@ -0,0 +1,100 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.connect;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.VersionTracker;
import de.florianmichael.viaforge.common.protocoltranslator.netty.VFNetworkManager;
import io.netty.channel.Channel;
import net.minecraft.network.NettyEncryptingDecoder;
import net.minecraft.network.NettyEncryptingEncoder;
import net.minecraft.network.NetworkManager;
import net.minecraft.util.LazyValue;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialoader.netty.VLLegacyPipeline;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import javax.crypto.Cipher;
import java.net.InetAddress;
@Mixin(NetworkManager.class)
public class MixinNetworkManager implements VFNetworkManager {
@Shadow private Channel channel;
@Shadow private boolean encrypted;
@Unique
private Cipher viaForge$decryptionCipher;
@Unique
private ProtocolVersion viaForge$targetVersion;
@Inject(method = "setupCompression", at = @At("RETURN"))
public void reorderPipeline(int p_setCompressionTreshold_1_, CallbackInfo ci) {
ViaForgeCommon.getManager().reorderCompression(channel);
}
@Inject(method = "setEncryptionKey", at = @At("HEAD"), cancellable = true)
private void storeEncryptionCiphers(Cipher p_244777_1_, Cipher p_244777_2_, CallbackInfo ci) {
if (viaForge$targetVersion != null && viaForge$targetVersion.olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
// Minecraft's encryption code is bad for us, we need to reorder the pipeline
ci.cancel();
// Minecraft 1.6.4 supports tile encryption 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.
this.viaForge$decryptionCipher = p_244777_1_;
// Enabling the encryption side
this.encrypted = true;
this.channel.pipeline().addBefore(VLLegacyPipeline.VIALEGACY_PRE_NETTY_LENGTH_REMOVER_NAME, "encrypt", new NettyEncryptingEncoder(p_244777_2_));
}
}
@Inject(method = "connectToServer", at = @At(value = "INVOKE", target = "Lio/netty/bootstrap/Bootstrap;group(Lio/netty/channel/EventLoopGroup;)Lio/netty/bootstrap/AbstractBootstrap;"), locals = LocalCapture.CAPTURE_FAILHARD)
private static void setTargetVersion(InetAddress address, int serverPort, boolean useNativeTransport, CallbackInfoReturnable<NetworkManager> cir, NetworkManager networkmanager, Class oclass, LazyValue lazyvalue) {
final VFNetworkManager mixinNetworkManager = (VFNetworkManager) networkmanager;
mixinNetworkManager.viaForge$setTrackedVersion(VersionTracker.getServerProtocolVersion(address));
}
@Override
public void viaForge$setupPreNettyDecryption() {
// 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_REMOVER_NAME, "decrypt", new NettyEncryptingDecoder(this.viaForge$decryptionCipher));
}
@Override
public ProtocolVersion viaForge$getTrackedVersion() {
return viaForge$targetVersion;
}
@Override
public void viaForge$setTrackedVersion(ProtocolVersion version) {
viaForge$targetVersion = version;
}
}

View File

@ -0,0 +1,44 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.connect;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.protocoltranslator.netty.VFNetworkManager;
import io.netty.channel.Channel;
import net.minecraft.network.NetworkManager;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(targets = "net.minecraft.network.NetworkManager$1")
public class MixinNetworkManager_1 {
@Final
@Mutable
NetworkManager val$networkmanager;
@Inject(method = "initChannel", at = @At(value = "TAIL"), remap = false)
private void hookViaPipeline(Channel channel, CallbackInfo ci) {
ViaForgeCommon.getManager().inject(channel, (VFNetworkManager) val$networkmanager);
}
}

View File

@ -0,0 +1,60 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.connect;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.gui.ExtendedServerData;
import de.florianmichael.viaforge.common.platform.VersionTracker;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.network.ServerPinger;
import net.minecraft.network.NetworkManager;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.net.InetAddress;
@Mixin(ServerPinger.class)
public class MixinServerPinger {
@Unique
private ServerData viaForge$serverData;
@Inject(method = "pingServer", at = @At("HEAD"))
public void trackServerData(ServerData server, Runnable p_147224_2_, CallbackInfo ci) {
viaForge$serverData = server;
}
@Redirect(method = "pingServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/NetworkManager;connectToServer(Ljava/net/InetAddress;IZ)Lnet/minecraft/network/NetworkManager;"))
public NetworkManager trackVersion(InetAddress address, int i, boolean b) {
ProtocolVersion version = ((ExtendedServerData) viaForge$serverData).viaForge$getVersion();
if (version == null) {
version = ViaForgeCommon.getManager().getTargetVersion();
}
VersionTracker.storeServerProtocolVersion(address, version);
viaForge$serverData = null;
return NetworkManager.connectToServer(address, i, b);
}
}

View File

@ -0,0 +1,56 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.fixes;
import com.mojang.authlib.GameProfile;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import net.minecraft.client.entity.player.AbstractClientPlayerEntity;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.world.ClientWorld;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
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(ClientPlayerEntity.class)
public class MixinClientPlayerEntity extends AbstractClientPlayerEntity {
@Shadow private boolean lastOnGround;
public MixinClientPlayerEntity(ClientWorld world, GameProfile profile) {
super(world, profile);
}
@Redirect(method = "sendPosition", at = @At(value = "FIELD", target = "Lnet/minecraft/client/entity/player/ClientPlayerEntity;lastOnGround:Z", ordinal = 0))
public boolean emulateIdlePacket(ClientPlayerEntity instance) {
if (ViaForgeCommon.getManager().getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
// <= 1.8 spams the idle packet instead of only sending it when the ground state changes
// So we invert the original logic:
// if (prevOnGround != onGround) sendPacket
// To be like:
// if (!onGround != onGround) sendPacket
// Which is the same as:
// if (true) sendPacket
return !onGround;
}
return lastOnGround;
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.provider;
import com.mojang.authlib.Agent;
import com.mojang.authlib.GameProfileRepository;
import com.mojang.authlib.HttpAuthenticationService;
import com.mojang.authlib.ProfileLookupCallback;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.yggdrasil.ProfileNotFoundException;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.provider.GameProfileFetcher;
import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.model.GameProfile;
import java.net.Proxy;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class ViaForgeGameProfileFetcher extends GameProfileFetcher {
public static final HttpAuthenticationService AUTHENTICATION_SERVICE = new YggdrasilAuthenticationService(Proxy.NO_PROXY, "");
public static final MinecraftSessionService SESSION_SERVICE = AUTHENTICATION_SERVICE.createMinecraftSessionService();
public static final GameProfileRepository GAME_PROFILE_REPOSITORY = AUTHENTICATION_SERVICE.createProfileRepository();
@Override
public UUID loadMojangUUID(String playerName) throws Exception {
final CompletableFuture<com.mojang.authlib.GameProfile> future = new CompletableFuture<>();
GAME_PROFILE_REPOSITORY.findProfilesByNames(new String[]{playerName}, Agent.MINECRAFT, new ProfileLookupCallback() {
@Override
public void onProfileLookupSucceeded(com.mojang.authlib.GameProfile profile) {
future.complete(profile);
}
@Override
public void onProfileLookupFailed(com.mojang.authlib.GameProfile profile, Exception exception) {
future.completeExceptionally(exception);
}
});
if (!future.isDone()) {
future.completeExceptionally(new ProfileNotFoundException());
}
return future.get().getId();
}
@Override
public GameProfile loadGameProfile(UUID uuid) throws Exception {
final com.mojang.authlib.GameProfile inProfile = new com.mojang.authlib.GameProfile(uuid, null);
final com.mojang.authlib.GameProfile mojangProfile = SESSION_SERVICE.fillProfileProperties(inProfile, true);
if (mojangProfile.equals(inProfile)) throw new ProfileNotFoundException();
final GameProfile gameProfile = new GameProfile(mojangProfile.getName(), mojangProfile.getId());
for (final java.util.Map.Entry<String, Property> entry : mojangProfile.getProperties().entries()) {
final Property prop = entry.getValue();
gameProfile.addProperty(new GameProfile.Property(prop.getName(), prop.getValue(), prop.getSignature()));
}
return gameProfile;
}
}

View File

@ -0,0 +1,18 @@
modLoader="javafml"
loaderVersion="[36,)"
license="GPL-3.0 license"
issueTrackerURL="https://github.com/ViaVersion/ViaForge/issues"
showAsResourcePack=false
[[mods]]
modId="viaforge"
version="${version}"
displayName="ViaForge"
displayURL="https://github.com/FlorianMichael"
logoFile="icon.png"
credits="Github contributors"
authors="FlorianMichael/EnZaXD"
description='''
Client-side Implementation of the Via* projects for Minecraft Forge
'''

View File

@ -0,0 +1,24 @@
{
"required": true,
"minVersion": "0.7.5",
"compatibilityLevel": "JAVA_8",
"package": "de.florianmichael.viaforge.mixin",
"client": [
"MixinAddServerScreen",
"connect.MixinClientLoginNetHandler",
"connect.MixinConnectingScreen_1",
"MixinDebugOverlayGui",
"MixinMainMenuScreen",
"MixinMultiplayerScreen",
"connect.MixinNetworkManager",
"connect.MixinNetworkManager_1",
"MixinServerData",
"MixinServerListScreen",
"connect.MixinServerPinger",
"fixes.MixinClientPlayerEntity"
],
"injectors": {
"defaultRequire": 1
},
"refmap": "mixins.viaforge-mc1165.refmap.json"
}

View File

@ -0,0 +1,7 @@
minecraft {
mappings channel: "official", version: "1.17.1"
}
dependencies {
minecraft "net.minecraftforge:forge:1.17.1-37.1.1"
}

View File

@ -0,0 +1,2 @@
maven_name=viaforge-mc1171
mc_version=1.17.1

View File

@ -0,0 +1,73 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.VFPlatform;
import de.florianmichael.viaforge.provider.ViaForgeGameProfileFetcher;
import net.minecraft.SharedConstants;
import net.minecraft.client.Minecraft;
import net.minecraft.client.User;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.provider.GameProfileFetcher;
import java.io.File;
import java.util.function.Supplier;
@Mod("viaforge")
public class ViaForge1171 implements VFPlatform {
public ViaForge1171() {
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onInit);
}
public void onInit(FMLCommonSetupEvent event) {
ViaForgeCommon.init(this);
}
@Override
public int getGameVersion() {
return SharedConstants.getProtocolVersion();
}
@Override
public Supplier<Boolean> isSingleplayer() {
return () -> Minecraft.getInstance().hasSingleplayerServer();
}
@Override
public File getLeadingDirectory() {
return Minecraft.getInstance().gameDirectory;
}
@Override
public void joinServer(String serverId) throws Throwable {
final User session = Minecraft.getInstance().getUser();
Minecraft.getInstance().getMinecraftSessionService().joinServer(session.getGameProfile(), session.getAccessToken(), serverId);
}
@Override
public GameProfileFetcher getGameProfileFetcher() {
return new ViaForgeGameProfileFetcher();
}
}

View File

@ -0,0 +1,171 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.gui;
import com.mojang.blaze3d.vertex.PoseStack;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.util.DumpUtil;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.ObjectSelectionList;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import net.raphimc.vialoader.util.ProtocolVersionList;
import org.lwjgl.glfw.GLFW;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
public class GuiProtocolSelector extends Screen {
public final Screen parent;
public final boolean simple;
public final FinishedCallback finishedCallback;
private SlotList list;
private String status;
private long time;
public static void open(final Minecraft minecraft) { // Bypass for some weird bytecode instructions errors in Forge
minecraft.setScreen(new GuiProtocolSelector(minecraft.screen));
}
public GuiProtocolSelector(final Screen parent) {
this(parent, false, (version, unused) -> {
// Default action is to set the target version and go back to the parent screen.
ViaForgeCommon.getManager().setTargetVersion(version);
});
}
public GuiProtocolSelector(final Screen parent, final boolean simple, final FinishedCallback finishedCallback) {
super(new TextComponent("ViaForge Protocol Selector"));
this.parent = parent;
this.simple = simple;
this.finishedCallback = finishedCallback;
}
@Override
public void init() {
super.init();
addRenderableWidget(new Button(5, height - 25, 20, 20, new TextComponent("<-"), b -> minecraft.setScreen(parent)));
if (!this.simple) {
addRenderableWidget(new Button(width - 105, 5, 100, 20, new TextComponent("Create dump"), b -> {
try {
minecraft.keyboardHandler.setClipboard(DumpUtil.postDump(UUID.randomUUID()).get());
setStatus(ChatFormatting.GREEN + "Dump created and copied to clipboard");
} catch (InterruptedException | ExecutionException e) {
setStatus(ChatFormatting.RED + "Failed to create dump: " + e.getMessage());
}
}));
addRenderableWidget(new Button(width - 105, height - 25, 100, 20, new TextComponent("Reload configs"), b -> Via.getManager().getConfigurationProvider().reloadConfigs()));
}
addWidget(list = new SlotList(minecraft, width, height, 3 + 3 /* start offset */ + (font.lineHeight + 2) * 3 /* title is 2 */, height - 30, font.lineHeight + 2));
}
public void setStatus(final String status) {
this.status = status;
this.time = System.currentTimeMillis();
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int actions) {
if (keyCode == GLFW.GLFW_KEY_ESCAPE) {
minecraft.setScreen(parent);
}
return super.keyPressed(keyCode, scanCode, actions);
}
@Override
public void render(PoseStack matrices, int p_230430_2_, int p_230430_3_, float p_230430_4_) {
if (System.currentTimeMillis() - this.time >= 10_000) {
this.status = null;
}
renderBackground(matrices);
this.list.render(matrices, p_230430_2_, p_230430_3_, p_230430_4_);
super.render(matrices, p_230430_2_, p_230430_3_, p_230430_4_);
matrices.pushPose();
matrices.scale(2.0F, 2.0F, 2.0F);
drawCenteredString(matrices, font, ChatFormatting.GOLD + "ViaForge", width / 4, 3, 16777215);
matrices.popPose();
drawCenteredString(matrices, font, "https://github.com/ViaVersion/ViaForge", width / 2, (font.lineHeight + 2) * 2 + 3, -1);
drawString(matrices, font, status != null ? status : "Discord: florianmichael", 3, 3, -1);
}
class SlotList extends ObjectSelectionList<SlotList.SlotEntry> {
public SlotList(Minecraft client, int width, int height, int top, int bottom, int slotHeight) {
super(client, width, height, top, bottom, slotHeight);
for (ProtocolVersion version : ProtocolVersionList.getProtocolsNewToOld()) {
addEntry(new SlotEntry(version));
}
}
public class SlotEntry extends ObjectSelectionList.Entry<SlotEntry> {
private final ProtocolVersion ProtocolVersion;
public SlotEntry(ProtocolVersion ProtocolVersion) {
this.ProtocolVersion = ProtocolVersion;
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
GuiProtocolSelector.this.finishedCallback.finished(ProtocolVersion, GuiProtocolSelector.this.parent);
return super.mouseClicked(mouseX, mouseY, button);
}
@Override
public Component getNarration() {
return new TextComponent(ProtocolVersion.getName());
}
@Override
public void render(PoseStack matrices, int p_93524_, int y, int p_93526_, int p_93527_, int p_93528_, int p_93529_, int p_93530_, boolean p_93531_, float p_93532_) {
final ProtocolVersion targetVersion = ViaForgeCommon.getManager().getTargetVersion();
String color;
if (targetVersion == ProtocolVersion) {
color = GuiProtocolSelector.this.simple ? ChatFormatting.GOLD.toString() : ChatFormatting.GREEN.toString();
} else {
color = GuiProtocolSelector.this.simple ? ChatFormatting.WHITE.toString() : ChatFormatting.DARK_RED.toString();
}
drawCenteredString(matrices, Minecraft.getInstance().font, color + ProtocolVersion.getName(), width / 2, y, -1);
}
}
}
public interface FinishedCallback {
void finished(final ProtocolVersion version, final Screen parent);
}
}

View File

@ -0,0 +1,45 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import net.minecraft.client.gui.components.DebugScreenOverlay;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@Mixin(DebugScreenOverlay.class)
public class MixinDebugScreenOverlay {
@Inject(method = "getSystemInformation", at = @At(value = "TAIL"))
public void addViaForgeVersion(CallbackInfoReturnable<List<String>> cir) {
final ViaForgeCommon common = ViaForgeCommon.getManager();
final ProtocolVersion version = ViaForgeCommon.getManager().getTargetVersion();
if (common.getConfig().isShowProtocolVersionInF3() && version != common.getNativeVersion() && !common.getPlatform().isSingleplayer().get()) {
cir.getReturnValue().add("");
cir.getReturnValue().add("ViaForge: " + version.toString());
}
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin;
import com.viaversion.viaversion.util.Pair;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.ViaForgeConfig;
import de.florianmichael.viaforge.gui.GuiProtocolSelector;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.DirectJoinServerScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
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(DirectJoinServerScreen.class)
public class MixinDirectJoinServerScreen extends Screen {
public MixinDirectJoinServerScreen(Component title) {
super(title);
}
@Inject(method = "init", at = @At("RETURN"))
public void hookViaForgeButton(CallbackInfo ci) {
final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig();
if (config.isShowDirectConnectButton()) {
final Pair<Integer, Integer> pos = config.getViaForgeButtonPosition().getPosition(this.width, this.height);
addRenderableWidget(new Button(pos.key(), pos.value(), 100, 20, new TextComponent("ViaForge"), b -> GuiProtocolSelector.open(minecraft)));
}
}
}

View File

@ -0,0 +1,69 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin;
import com.viaversion.viaversion.util.Pair;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.gui.ExtendedServerData;
import de.florianmichael.viaforge.common.platform.ViaForgeConfig;
import de.florianmichael.viaforge.gui.GuiProtocolSelector;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.EditServerScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
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.callback.CallbackInfo;
@Mixin(EditServerScreen.class)
public class MixinEditServerScreen extends Screen {
@Shadow
@Final
private ServerData serverData;
public MixinEditServerScreen(Component title) {
super(title);
}
@Inject(method = "init", at = @At("RETURN"))
public void initGui(CallbackInfo ci) {
final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig();
if (config.isShowAddServerButton()) {
final Pair<Integer, Integer> pos = config.getAddServerScreenButtonPosition().getPosition(this.width, this.height);
final ProtocolVersion target = ((ExtendedServerData) serverData).viaForge$getVersion();
addRenderableWidget(new Button(pos.key(), pos.value(), 100, 20, new TextComponent(target != null ? target.getName() : "Set Version"), b -> {
minecraft.setScreen(new GuiProtocolSelector(this, true, (version, parent) -> {
// Set version and go back to the parent screen.
((ExtendedServerData) serverData).viaForge$setVersion(version);
minecraft.setScreen(parent);
}));
}));
}
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin;
import com.viaversion.viaversion.util.Pair;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.ViaForgeConfig;
import de.florianmichael.viaforge.gui.GuiProtocolSelector;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.multiplayer.JoinMultiplayerScreen;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
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(JoinMultiplayerScreen.class)
public class MixinJoinMultiplayerScreen extends Screen {
public MixinJoinMultiplayerScreen(Component title) {
super(title);
}
@Inject(method = "init", at = @At("RETURN"))
public void hookViaForgeButton(CallbackInfo ci) {
final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig();
if (config.isShowMainMenuButton()) {
final Pair<Integer, Integer> pos = config.getViaForgeButtonPosition().getPosition(this.width, this.height);
addRenderableWidget(new Button(pos.key(), pos.value(), 100, 20, new TextComponent("ViaForge"), buttons -> GuiProtocolSelector.open(minecraft)));
}
}
}

View File

@ -0,0 +1,70 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin;
import de.florianmichael.viaforge.common.gui.ExtendedServerData;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.nbt.CompoundTag;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
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.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@Mixin(ServerData.class)
public class MixinServerData implements ExtendedServerData {
@Unique
private ProtocolVersion viaForge$version;
@Inject(method = "write", at = @At(value = "INVOKE", target = "Lnet/minecraft/nbt/CompoundTag;putString(Ljava/lang/String;Ljava/lang/String;)V", ordinal = 0), locals = LocalCapture.CAPTURE_FAILHARD)
public void saveVersion(CallbackInfoReturnable<CompoundTag> cir, CompoundTag compoundtag) {
if (viaForge$version != null) {
compoundtag.putString("viaForge$version", viaForge$version.getName());
}
}
@Inject(method = "read", at = @At(value = "TAIL"))
private static void getVersion(CompoundTag compoundnbt, CallbackInfoReturnable<ServerData> cir) {
if (compoundnbt.contains("viaForge$version")) {
((ExtendedServerData) cir.getReturnValue()).viaForge$setVersion(ProtocolVersion.getClosest(compoundnbt.getString("viaForge$version")));
}
}
@Inject(method = "copyFrom", at = @At("HEAD"))
public void track(ServerData serverDataIn, CallbackInfo ci) {
if (serverDataIn instanceof ExtendedServerData) {
viaForge$version = ((ExtendedServerData) serverDataIn).viaForge$getVersion();
}
}
@Override
public ProtocolVersion viaForge$getVersion() {
return viaForge$version;
}
@Override
public void viaForge$setVersion(ProtocolVersion version) {
viaForge$version = version;
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin;
import com.viaversion.viaversion.util.Pair;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.ViaForgeConfig;
import de.florianmichael.viaforge.gui.GuiProtocolSelector;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.TitleScreen;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
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(TitleScreen.class)
public class MixinTitleScreen extends Screen {
public MixinTitleScreen(Component title) {
super(title);
}
@Inject(method = "init", at = @At("RETURN"))
public void hookViaForgeButton(CallbackInfo ci) {
final ViaForgeConfig config = ViaForgeCommon.getManager().getConfig();
if (config.isShowMainMenuButton()) {
final Pair<Integer, Integer> pos = config.getViaForgeButtonPosition().getPosition(this.width, this.height);
addRenderableWidget(new Button(pos.key(), pos.value(), 100, 20, new TextComponent("ViaForge"), buttons -> GuiProtocolSelector.open(minecraft)));
}
}
}

View File

@ -0,0 +1,58 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.connect;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.exceptions.AuthenticationException;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.viaversion.viaversion.api.connection.UserConnection;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.protocoltranslator.netty.VFNetworkManager;
import net.minecraft.client.multiplayer.ClientHandshakePacketListenerImpl;
import net.minecraft.network.Connection;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
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;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@SuppressWarnings("DataFlowIssue")
@Mixin(ClientHandshakePacketListenerImpl.class)
public class MixinClientHandshakePacketListenerImpl {
@Shadow @Final private Connection connection;
@Redirect(method = "authenticateServer", at = @At(value = "INVOKE", target = "Lcom/mojang/authlib/minecraft/MinecraftSessionService;joinServer(Lcom/mojang/authlib/GameProfile;Ljava/lang/String;Ljava/lang/String;)V"))
public void onlyJoinServerIfPremium(MinecraftSessionService instance, GameProfile profile, String authenticationToken, String serverId) throws AuthenticationException {
final VFNetworkManager mixinConnection = (VFNetworkManager) connection;
if (mixinConnection.viaForge$getTrackedVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
final UserConnection user = connection.channel().attr(ViaForgeCommon.LOCAL_VIA_USER).get();
if (user != null && user.has(ProtocolMetadataStorage.class) && !user.get(ProtocolMetadataStorage.class).authenticate) {
// We are in the 1.7 -> 1.6 protocol, so we need to skip the joinServer call
// if the server is in offline mode, due the packet changes <-> networking changes
// Minecraft's networking code is bad for us.
return;
}
}
instance.joinServer(profile, authenticationToken, serverId);
}
}

View File

@ -0,0 +1,47 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.connect;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.gui.ExtendedServerData;
import de.florianmichael.viaforge.common.platform.VersionTracker;
import net.minecraft.client.Minecraft;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.net.InetSocketAddress;
import java.util.Optional;
@Mixin(targets = "net.minecraft.client.gui.screens.ConnectScreen$1")
public class MixinConnectScreen_1 {
@Redirect(method = "run", at = @At(value = "INVOKE", target = "Ljava/util/Optional;get()Ljava/lang/Object;"))
public Object trackServerVersion(Optional instance) {
final InetSocketAddress address = (InetSocketAddress) instance.get();
ProtocolVersion version = ((ExtendedServerData) Minecraft.getInstance().getCurrentServer()).viaForge$getVersion();
if (version == null) {
version = ViaForgeCommon.getManager().getTargetVersion();
}
VersionTracker.storeServerProtocolVersion(address.getAddress(), version);
return address;
}
}

View File

@ -0,0 +1,102 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.connect;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.VersionTracker;
import de.florianmichael.viaforge.common.protocoltranslator.netty.VFNetworkManager;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import net.minecraft.network.CipherDecoder;
import net.minecraft.network.CipherEncoder;
import net.minecraft.network.Connection;
import net.minecraft.util.LazyLoadedValue;
import net.raphimc.vialegacy.api.LegacyProtocolVersion;
import net.raphimc.vialoader.netty.VLLegacyPipeline;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import javax.crypto.Cipher;
import java.net.InetSocketAddress;
@Mixin(Connection.class)
public class MixinConnection implements VFNetworkManager {
@Shadow private Channel channel;
@Shadow private boolean encrypted;
@Unique
private Cipher viaForge$decryptionCipher;
@Unique
private ProtocolVersion viaForge$targetVersion;
@Inject(method = "setupCompression", at = @At("RETURN"))
public void reorderPipeline(int p_129485_, boolean p_182682_, CallbackInfo ci) {
ViaForgeCommon.getManager().reorderCompression(channel);
}
@Inject(method = "setEncryptionKey", at = @At("HEAD"), cancellable = true)
private void storeEncryptionCiphers(Cipher p_244777_1_, Cipher p_244777_2_, CallbackInfo ci) {
if (viaForge$targetVersion != null && viaForge$targetVersion.olderThanOrEqualTo(LegacyProtocolVersion.r1_6_4)) {
// Minecraft's encryption code is bad for us, we need to reorder the pipeline
ci.cancel();
// Minecraft 1.6.4 supports tile encryption 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.
this.viaForge$decryptionCipher = p_244777_1_;
// Enabling the encryption side
this.encrypted = true;
this.channel.pipeline().addBefore(VLLegacyPipeline.VIALEGACY_PRE_NETTY_LENGTH_REMOVER_NAME, "encrypt", new CipherEncoder(p_244777_2_));
}
}
@Inject(method = "connectToServer", at = @At(value = "INVOKE", target = "Lio/netty/bootstrap/Bootstrap;group(Lio/netty/channel/EventLoopGroup;)Lio/netty/bootstrap/AbstractBootstrap;"), locals = LocalCapture.CAPTURE_FAILHARD)
private static void setTargetVersion(InetSocketAddress p_178301_, boolean p_178302_, CallbackInfoReturnable<Connection> cir, Connection connection, Class<? extends SocketChannel> oclass, LazyLoadedValue<? extends EventLoopGroup> lazyloadedvalue) {
final VFNetworkManager mixinConnection = (VFNetworkManager) connection;
mixinConnection.viaForge$setTrackedVersion(VersionTracker.getServerProtocolVersion(p_178301_.getAddress()));
}
@Override
public void viaForge$setupPreNettyDecryption() {
// 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_REMOVER_NAME, "decrypt", new CipherDecoder(this.viaForge$decryptionCipher));
}
@Override
public ProtocolVersion viaForge$getTrackedVersion() {
return viaForge$targetVersion;
}
@Override
public void viaForge$setTrackedVersion(ProtocolVersion version) {
viaForge$targetVersion = version;
}
}

View File

@ -1,6 +1,6 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2023 FlorianMichael/EnZaXD and contributors
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -15,24 +15,25 @@
* 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.viaforge.mixin.impl;
package de.florianmichael.viaforge.mixin.connect;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.protocoltranslator.netty.VFNetworkManager;
import io.netty.channel.Channel;
import net.minecraft.network.NetworkManager;
import net.raphimc.vialoader.netty.CompressionReorderEvent;
import io.netty.channel.ChannelHandler;
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.callback.CallbackInfo;
@Mixin(NetworkManager.class)
public class MixinNetworkManager {
@Mixin(targets = "net.minecraft.network.Connection$1")
public class MixinConnection_1 {
@Shadow private Channel channel;
@Inject(method = "setCompressionThreshold", at = @At("RETURN"))
public void reOrderPipeline(int p_setCompressionTreshold_1_, CallbackInfo ci) {
channel.pipeline().fireUserEventTriggered(CompressionReorderEvent.INSTANCE);
@Inject(method = "initChannel", at = @At("TAIL"))
private void hookViaPipeline(Channel p_129552_, CallbackInfo ci) {
final ChannelHandler connection = p_129552_.pipeline().get("packet_handler");
ViaForgeCommon.getManager().inject(p_129552_, (VFNetworkManager) connection);
}
}

View File

@ -0,0 +1,60 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.connect;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.gui.ExtendedServerData;
import de.florianmichael.viaforge.common.platform.VersionTracker;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.multiplayer.ServerStatusPinger;
import net.minecraft.network.Connection;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
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.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.net.InetSocketAddress;
@Mixin(ServerStatusPinger.class)
public class MixinServerStatusPinger {
@Unique
private ServerData viaForge$serverData;
@Inject(method = "pingServer", at = @At("HEAD"))
public void trackServerData(ServerData server, Runnable p_147224_2_, CallbackInfo ci) {
viaForge$serverData = server;
}
@Redirect(method = "pingServer", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/Connection;connectToServer(Ljava/net/InetSocketAddress;Z)Lnet/minecraft/network/Connection;"))
public Connection trackVersion(InetSocketAddress oclass, boolean lazyloadedvalue) {
ProtocolVersion version = ((ExtendedServerData) viaForge$serverData).viaForge$getVersion();
if (version == null) {
version = ViaForgeCommon.getManager().getTargetVersion();
}
VersionTracker.storeServerProtocolVersion(oclass.getAddress(), version);
viaForge$serverData = null;
return Connection.connectToServer(oclass, lazyloadedvalue);
}
}

View File

@ -0,0 +1,56 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.mixin.fixes;
import com.mojang.authlib.GameProfile;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.player.LocalPlayer;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
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(LocalPlayer.class)
public class MixinLocalPlayer extends AbstractClientPlayer {
@Shadow private boolean lastOnGround;
public MixinLocalPlayer(ClientLevel level, GameProfile profile) {
super(level, profile);
}
@Redirect(method = "sendPosition", at = @At(value = "FIELD", target = "Lnet/minecraft/client/player/LocalPlayer;lastOnGround:Z", ordinal = 0))
public boolean emulateIdlePacket(LocalPlayer instance) {
if (ViaForgeCommon.getManager().getTargetVersion().olderThanOrEqualTo(ProtocolVersion.v1_8)) {
// <= 1.8 spams the idle packet instead of only sending it when the ground state changes
// So we invert the original logic:
// if (prevOnGround != onGround) sendPacket
// To be like:
// if (!onGround != onGround) sendPacket
// Which is the same as:
// if (true) sendPacket
return !onGround;
}
return lastOnGround;
}
}

View File

@ -0,0 +1,77 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge.provider;
import com.mojang.authlib.Agent;
import com.mojang.authlib.GameProfileRepository;
import com.mojang.authlib.HttpAuthenticationService;
import com.mojang.authlib.ProfileLookupCallback;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import com.mojang.authlib.properties.Property;
import com.mojang.authlib.yggdrasil.ProfileNotFoundException;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.model.GameProfile;
import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.provider.GameProfileFetcher;
import java.net.Proxy;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class ViaForgeGameProfileFetcher extends GameProfileFetcher {
public static final HttpAuthenticationService AUTHENTICATION_SERVICE = new YggdrasilAuthenticationService(Proxy.NO_PROXY, "");
public static final MinecraftSessionService SESSION_SERVICE = AUTHENTICATION_SERVICE.createMinecraftSessionService();
public static final GameProfileRepository GAME_PROFILE_REPOSITORY = AUTHENTICATION_SERVICE.createProfileRepository();
@Override
public UUID loadMojangUUID(String playerName) throws Exception {
final CompletableFuture<com.mojang.authlib.GameProfile> future = new CompletableFuture<>();
GAME_PROFILE_REPOSITORY.findProfilesByNames(new String[]{playerName}, Agent.MINECRAFT, new ProfileLookupCallback() {
@Override
public void onProfileLookupSucceeded(com.mojang.authlib.GameProfile profile) {
future.complete(profile);
}
@Override
public void onProfileLookupFailed(com.mojang.authlib.GameProfile profile, Exception exception) {
future.completeExceptionally(exception);
}
});
if (!future.isDone()) {
future.completeExceptionally(new ProfileNotFoundException());
}
return future.get().getId();
}
@Override
public GameProfile loadGameProfile(UUID uuid) throws Exception {
final com.mojang.authlib.GameProfile inProfile = new com.mojang.authlib.GameProfile(uuid, null);
final com.mojang.authlib.GameProfile mojangProfile = SESSION_SERVICE.fillProfileProperties(inProfile, true);
if (mojangProfile.equals(inProfile)) throw new ProfileNotFoundException();
final GameProfile gameProfile = new GameProfile(mojangProfile.getName(), mojangProfile.getId());
for (final java.util.Map.Entry<String, Property> entry : mojangProfile.getProperties().entries()) {
final Property prop = entry.getValue();
gameProfile.addProperty(new GameProfile.Property(prop.getName(), prop.getValue(), prop.getSignature()));
}
return gameProfile;
}
}

View File

@ -0,0 +1,18 @@
modLoader="javafml"
loaderVersion="[37,)"
license="GPL-3.0 license"
issueTrackerURL="https://github.com/ViaVersion/ViaForge/issues"
showAsResourcePack=false
[[mods]]
modId="viaforge"
version="${version}"
displayName="ViaForge"
displayURL="https://github.com/FlorianMichael"
logoFile="icon.png"
credits="Github contributors"
authors="FlorianMichael/EnZaXD"
description='''
Client-side Implementation of the Via* projects for Minecraft Forge
'''

View File

@ -0,0 +1,25 @@
{
"required": true,
"minVersion": "0.7.5",
"compatibilityLevel": "JAVA_8",
"package": "de.florianmichael.viaforge.mixin",
"client": [
"connect.MixinClientHandshakePacketListenerImpl",
"connect.MixinConnection",
"connect.MixinConnection_1",
"MixinDebugScreenOverlay",
"MixinDirectJoinServerScreen",
"MixinEditServerScreen",
"MixinJoinMultiplayerScreen",
"MixinServerData",
"connect.MixinServerStatusPinger",
"MixinTitleScreen",
"fixes.MixinLocalPlayer",
"connect.MixinConnection_1",
"connect.MixinConnectScreen_1"
],
"injectors": {
"defaultRequire": 1
},
"refmap": "mixins.viaforge-mc1171.refmap.json"
}

View File

@ -0,0 +1,7 @@
minecraft {
mappings channel: "official", version: "1.18.2"
}
dependencies {
minecraft "net.minecraftforge:forge:1.18.2-40.2.0"
}

View File

@ -0,0 +1,2 @@
maven_name=viaforge-mc1182
mc_version=1.18.2

View File

@ -0,0 +1,73 @@
/*
* This file is part of ViaForge - https://github.com/FlorianMichael/ViaForge
* Copyright (C) 2021-2024 FlorianMichael/EnZaXD <florian.michael07@gmail.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.florianmichael.viaforge;
import de.florianmichael.viaforge.common.ViaForgeCommon;
import de.florianmichael.viaforge.common.platform.VFPlatform;
import de.florianmichael.viaforge.provider.ViaForgeGameProfileFetcher;
import net.minecraft.SharedConstants;
import net.minecraft.client.Minecraft;
import net.minecraft.client.User;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.raphimc.vialegacy.protocol.release.r1_7_6_10tor1_8.provider.GameProfileFetcher;
import java.io.File;
import java.util.function.Supplier;
@Mod("viaforge")
public class ViaForge1182 implements VFPlatform {
public ViaForge1182() {
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::onInit);
}
private void onInit(FMLCommonSetupEvent event) {
ViaForgeCommon.init(this);
}
@Override
public int getGameVersion() {
return SharedConstants.getProtocolVersion();
}
@Override
public Supplier<Boolean> isSingleplayer() {
return () -> Minecraft.getInstance().hasSingleplayerServer();
}
@Override
public File getLeadingDirectory() {
return Minecraft.getInstance().gameDirectory;
}
@Override
public void joinServer(String serverId) throws Throwable {
final User session = Minecraft.getInstance().getUser();
Minecraft.getInstance().getMinecraftSessionService().joinServer(session.getGameProfile(), session.getAccessToken(), serverId);
}
@Override
public GameProfileFetcher getGameProfileFetcher() {
return new ViaForgeGameProfileFetcher();
}
}

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