├── .github
└── workflows
│ ├── build.yml
│ └── checkMappings.yml
├── .gitignore
├── .gitmodules
├── .run
├── BungeeCord Server.run.xml
└── Velocity Server.run.xml
├── HEADER.txt
├── Jenkinsfile
├── LICENSE
├── README.md
├── build.gradle
├── buildSrc
├── build.gradle
└── src
│ └── main
│ └── java
│ └── com
│ └── ishland
│ └── buildscript
│ └── ParseGItHubActionChangelog.java
├── bungee
├── build.gradle
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── ishland
│ │ └── raknetify
│ │ └── bungee
│ │ ├── RaknetifyBungeePlugin.java
│ │ ├── connection
│ │ ├── RakNetBungeeClientChannelEventListener.java
│ │ ├── RakNetBungeeConnectionUtil.java
│ │ ├── RakNetBungeePingUpdater.java
│ │ ├── RakNetBungeeServerChannelEventListener.java
│ │ └── StripFrameHandler.java
│ │ └── init
│ │ ├── BungeeRaknetifyServer.java
│ │ └── InjectedSet.java
│ └── resources
│ └── bungee.yml
├── common
├── build.gradle
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── ishland
│ │ └── raknetify
│ │ └── common
│ │ ├── Constants.java
│ │ ├── connection
│ │ ├── ByteBufCopyDecoder.java
│ │ ├── FrameDataBlocker.java
│ │ ├── MetricsSynchronizationHandler.java
│ │ ├── MultiChannelingStreamingCompression.java
│ │ ├── MultiChannellingEncryption.java
│ │ ├── NoFlush.java
│ │ ├── PacketEncryptionManager.java
│ │ ├── RakNetConnectionUtil.java
│ │ ├── RakNetSimpleMultiChannelCodec.java
│ │ ├── RaknetifyEventLoops.java
│ │ ├── SimpleMetricsLogger.java
│ │ ├── SynchronizationLayer.java
│ │ └── multichannel
│ │ │ └── CustomPayloadChannel.java
│ │ ├── data
│ │ └── ProtocolMultiChannelMappings.java
│ │ ├── package-info.java
│ │ └── util
│ │ ├── DebugUtil.java
│ │ ├── MathUtil.java
│ │ ├── NetworkInterfaceListener.java
│ │ ├── PrefixUtil.java
│ │ ├── ReflectionUtil.java
│ │ └── ThreadLocalUtil.java
│ └── resources
│ └── raknetify-channel-mappings.json
├── fabric
├── build.gradle
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── ishland
│ │ └── raknetify
│ │ └── fabric
│ │ ├── RaknetifyFabric.java
│ │ ├── common
│ │ ├── compat
│ │ │ ├── package-info.java
│ │ │ └── viafabric
│ │ │ │ └── ViaFabricCompatInjector.java
│ │ ├── connection
│ │ │ ├── MultiChannellingPacketCapture.java
│ │ │ ├── RakNetClientConnectionUtil.java
│ │ │ ├── RakNetCompressionCompatibilityHandler.java
│ │ │ ├── RakNetFabricChannelEventListener.java
│ │ │ ├── RakNetFabricConnectionUtil.java
│ │ │ ├── RakNetMultiChannel.java
│ │ │ ├── RakNetNetworkTransitionUtil.java
│ │ │ └── encryption
│ │ │ │ └── PacketEncryptionManagerInterface.java
│ │ ├── package-info.java
│ │ ├── quirks
│ │ │ └── ClientHungerManager.java
│ │ └── util
│ │ │ ├── FieldSignatureParser.java
│ │ │ ├── MultiVersionUtil.java
│ │ │ └── NetworkStates.java
│ │ └── mixin
│ │ ├── RaknetifyFabricMixinPlugin.java
│ │ ├── access
│ │ ├── IClientConnection.java
│ │ ├── IClientPlayNetworkHandler.java
│ │ ├── INetworkState1_20_4.java
│ │ ├── INetworkStateInternalPacketHandler.java
│ │ ├── IPacketCodecDispatcher.java
│ │ ├── IPacketCodecDispatcherPacketType.java
│ │ ├── IPacketEncryptionManager.java
│ │ └── IServerPlayNetworkHandler.java
│ │ ├── client
│ │ ├── MixinClientPlayNetworkHandler.java
│ │ ├── MixinConnectionScreen1.java
│ │ ├── MixinMultiplayerServerListPinger.java
│ │ ├── MixinMultiplayerServerListPinger1.java
│ │ ├── MixinMultiplayerServerListPinger1_20_2.java
│ │ ├── MixinMultiplayerServerListPinger1_20_5.java
│ │ └── hud
│ │ │ └── MixinDebugHud.java
│ │ ├── common
│ │ ├── MixinCCConnect.java
│ │ ├── MixinClientConnection.java
│ │ ├── MixinClientConnection1.java
│ │ ├── MixinClientConnection1_20_2.java
│ │ ├── MixinServerAddress.java
│ │ ├── encryption
│ │ │ ├── MixinClientConnection.java
│ │ │ ├── MixinPacketDecryptor.java
│ │ │ ├── MixinPacketEncryptionManager.java
│ │ │ └── MixinPacketEncryptor.java
│ │ └── quirks
│ │ │ ├── MixinPlayerEntity.java
│ │ │ └── MixinSampleSubscriptionTracker.java
│ │ ├── compat
│ │ ├── fabricapi
│ │ │ └── MixinServerLoginNetworkAddon.java
│ │ ├── krypton
│ │ │ └── MixinServerLoginNetworkHandler.java
│ │ ├── package-info.java
│ │ └── qsl
│ │ │ └── MixinServerLoginNetworkAddon.java
│ │ ├── package-info.java
│ │ └── server
│ │ ├── MixinPlayerManager1_20_1.java
│ │ ├── MixinPlayerManager1_20_2.java
│ │ ├── MixinServerCommonNetworkHandler.java
│ │ ├── MixinServerLoginNetworkHandler.java
│ │ ├── MixinServerNetworkIo.java
│ │ ├── MixinServerNetworkIo1.java
│ │ └── MixinServerPlayNetworkHandler1_20_1.java
│ └── resources
│ ├── fabric.mod.json
│ ├── raknetify-fabric.accesswidener
│ └── raknetify-fabric.mixins.json
├── genMappings.sh
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── jitpack.yml
├── modrinth_license.txt
├── settings.gradle
└── velocity
├── HEADER.txt
├── LICENSE
├── build.gradle
└── src
└── main
├── java
└── com
│ └── ishland
│ └── raknetify
│ └── velocity
│ ├── RaknetifyVelocityLaunchWrapper.java
│ ├── RaknetifyVelocityPlugin.java
│ ├── connection
│ ├── RakNetVelocityChannelEventListener.java
│ ├── RakNetVelocityConnectionUtil.java
│ └── RakNetVelocityServerChannelEventListener.java
│ └── init
│ ├── VelocityPacketRegistryInjector.java
│ └── VelocityRaknetifyServer.java
└── resources
└── velocity-plugin.json
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | # Automatically build the project and run any configured tests for every push
2 | # and submitted pull request. This can help catch issues that only occur on
3 | # certain platforms or Java versions, and provides a first line of defence
4 | # against bad commits.
5 |
6 | name: build
7 | on: [pull_request, push]
8 |
9 | jobs:
10 | build:
11 | strategy:
12 | matrix:
13 | # Use these Java versions
14 | java: [
15 | 21, # Current Java LTS & minimum supported by Minecraft
16 | ]
17 | # and run on both Linux and Windows
18 | os: [ubuntu-24.04]
19 | runs-on: ${{ matrix.os }}
20 | steps:
21 | - name: checkout repository
22 | uses: actions/checkout@v4
23 | with:
24 | fetch-depth: 0
25 | submodules: true
26 | - name: validate gradle wrapper
27 | uses: gradle/wrapper-validation-action@v1
28 | - name: setup jdk ${{ matrix.java }}
29 | uses: actions/setup-java@v2
30 | with:
31 | distribution: 'zulu'
32 | java-version: ${{ matrix.java }}
33 | java-package: jdk
34 | - uses: actions/cache@v4
35 | with:
36 | path: |
37 | ~/.gradle/caches
38 | ~/.gradle/wrapper
39 | ./.gradle/loom-cache
40 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
41 | restore-keys: |
42 | ${{ runner.os }}-gradle-
43 | - name: build
44 | run: ./gradlew build
45 | - name: upload to modrinth and curseforge
46 | run: ./gradlew modrinth curseforge
47 | if: github.ref == 'refs/heads/master'
48 | env:
49 | MODRINTH_TOKEN: ${{ secrets.MODRINTH_UPLOAD_TOKEN }}
50 | CURSEFORGE_TOKEN: ${{ secrets.CURSEFORGE_API_TOKEN }}
51 | GITHUB_EVENT_RAW_PATH: ${{ github.event_path }}
52 | continue-on-error: true
53 | - name: capture build artifacts
54 | if: ${{ runner.os == 'Linux' && matrix.java == '21' }} # Only upload artifacts built from latest java on one OS
55 | uses: actions/upload-artifact@v4
56 | with:
57 | name: Artifacts
58 | path: ./**/build/libs/*-all.jar
59 |
--------------------------------------------------------------------------------
/.github/workflows/checkMappings.yml:
--------------------------------------------------------------------------------
1 | name: check mappings
2 | on: [pull_request, push]
3 |
4 | jobs:
5 | checkMappings:
6 | strategy:
7 | matrix:
8 | # Use these Java versions
9 | java: [
10 | 21, # Current Java LTS & minimum supported by Minecraft
11 | ]
12 | # and run on both Linux and Windows
13 | os: [ubuntu-24.04]
14 | runs-on: ${{ matrix.os }}
15 | steps:
16 | - name: checkout repository
17 | uses: actions/checkout@v2
18 | with:
19 | fetch-depth: 0
20 | submodules: true
21 | - name: validate gradle wrapper
22 | uses: gradle/wrapper-validation-action@v1
23 | - name: setup jdk ${{ matrix.java }}
24 | uses: actions/setup-java@v2
25 | with:
26 | distribution: 'zulu'
27 | java-version: ${{ matrix.java }}
28 | java-package: jdk
29 | - uses: actions/cache@v4
30 | with:
31 | path: |
32 | ~/.gradle/caches
33 | ~/.gradle/wrapper
34 | ./.gradle/loom-cache
35 | key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
36 | restore-keys: |
37 | ${{ runner.os }}-gradle-
38 | - name: "cache mappingsGen"
39 | uses: actions/cache@v4
40 | with:
41 | path: |
42 | ./run-mappingsGen
43 | key: ${{ runner.os }}-mappingsGen-${{ hashFiles('./genMappings.sh') }}
44 | restore-keys: |
45 | ${{ runner.os }}-mappingsGen-
46 | - name: generate mappings
47 | env:
48 | MAPPINGS_GEN_FRESH: true
49 | run: ./genMappings.sh
50 | - name: fail if mappings changed
51 | run: |
52 | git update-index --refresh
53 | if ! git diff-index --quiet HEAD --; then
54 | echo "Mappings changed, please commit them"
55 | git diff
56 | git diff --staged
57 | exit 1
58 | fi
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # gradle
2 |
3 | .gradle/
4 | build/
5 | out/
6 | classes/
7 |
8 | # eclipse
9 |
10 | *.launch
11 |
12 | # idea
13 |
14 | .idea/
15 | *.iml
16 | *.ipr
17 | *.iws
18 |
19 | # vscode
20 |
21 | .settings/
22 | .vscode/
23 | bin/
24 | .classpath
25 | .project
26 |
27 | # macos
28 |
29 | *.DS_Store
30 |
31 | # fabric
32 |
33 | run*/
34 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "netty-raknet"]
2 | path = netty-raknet
3 | url = https://github.com/RelativityMC/netty-raknet.git
4 |
--------------------------------------------------------------------------------
/.run/BungeeCord Server.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.run/Velocity Server.run.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/HEADER.txt:
--------------------------------------------------------------------------------
1 | This file is a part of the Raknetify project, licensed under MIT.
2 |
3 | Copyright (c) 2022-2025 ishland
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Jenkinsfile:
--------------------------------------------------------------------------------
1 | pipeline {
2 | agent { label 'slave' }
3 | options { timestamps() }
4 | stages {
5 | stage('SCM-SKIP') {
6 | steps {
7 | scmSkip(skipPattern:'.*\\[ci skip\\].*')
8 | }
9 | }
10 | stage('Build') {
11 | tools {
12 | jdk "OpenJDK 21"
13 | }
14 | steps {
15 | withMaven(
16 | maven: '3',
17 | mavenLocalRepo: '.repository',
18 | publisherStrategy: 'EXPLICIT'
19 | ) {
20 | sh 'git fetch --tags'
21 | sh 'git reset --hard'
22 | sh './gradlew clean build'
23 | }
24 | }
25 | post {
26 | success {
27 | archiveArtifacts artifacts: "**/build/libs/*-all.jar", fingerprint: true
28 | }
29 | failure {
30 | cleanWs()
31 | }
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2022-2025 ishland
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Raknetify
2 | A Fabric mod / Velocity plugin / BungeeCord plugin that uses RakNet to improve multiplayer experience significantly
3 | under unreliable and rate-limited connections.
4 |
5 | # Features
6 | - Higher reliability and lower latency under unreliable and rate-limited client connections.
7 | - Uses RakNet's multiple channels with priorities to achieve higher responsiveness.
8 | - Supports ViaVersion client-side and ViaVersion server-side.
9 |
10 | # How to use it?
11 |
12 | ## Prerequisites
13 | - Raknetify is designed to work on Minecraft 1.17.1+
14 | Note: On proxies such as Velocity and BungeeCord, **unsupported client version** will cause
15 | multi-channelling failing to initialize, causing **reduced responsiveness**.
16 | - You need to have a UDP port opened at the same port number of your normal server port.
17 |
18 | ## Installation and usage
19 | - Download the latest release from
20 | [GitHub](https://github.com/RelativityMC/raknetify/releases)
21 | [Modrinth (Fabric)](https://modrinth.com/mod/raknetify/versions)
22 | [CurseForge (Fabric)](https://www.curseforge.com/minecraft/mc-mods/raknetify/files)
23 | [SpigotMC (BungeeCord)](https://www.spigotmc.org/resources/raknetify-bungeecord.102509/)
24 | or development builds from [CodeMC](https://ci.codemc.io/job/RelativityMC/job/raknetify/)
25 | - Install the mod on both client and server. (Installation on backend servers are not needed if using on proxies)
26 | - Prefix your server address with `raknet;` (or `raknetl;` to use high mtu) and save or connect directly.
27 | (e.g. `raknet;example.com`)
28 | - Enjoy!
29 |
30 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'fabric-loom' version '1.8-SNAPSHOT' apply false
3 | id 'com.github.johnrengelman.shadow' version '7.1.0' apply false
4 | id 'org.cadixdev.licenser' version '0.6.1' apply false
5 | id 'com.modrinth.minotaur' version '2.+' apply false
6 | id 'com.matthewprenger.cursegradle' version '1.4.0' apply false
7 | }
8 |
9 | subprojects {
10 | apply plugin: 'java'
11 | apply plugin: 'java-library'
12 | apply plugin: 'maven-publish'
13 | apply plugin: 'org.cadixdev.licenser'
14 |
15 | sourceCompatibility = JavaVersion.VERSION_17
16 | targetCompatibility = JavaVersion.VERSION_17
17 |
18 | version = project.mod_version + "." + getVersionSuffix()
19 |
20 | license {
21 | header = rootProject.file('HEADER.txt')
22 | }
23 |
24 | repositories {
25 | mavenCentral()
26 | maven { url 'https://jitpack.io' }
27 | maven { url 'https://repo.codemc.org/repository/maven-public' }
28 | maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
29 | }
30 |
31 | // configure the maven publication
32 | publishing {
33 | publications {
34 | mavenJava(MavenPublication) {
35 | from components.java
36 | }
37 | }
38 |
39 | // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
40 | repositories {
41 | // Add repositories to publish to here.
42 | // Notice: This block does NOT have the same function as the block in the top level.
43 | // The repositories here will be used for publishing your artifact, not for
44 | // retrieving dependencies.
45 | }
46 | }
47 |
48 | tasks.withType(AbstractArchiveTask) {
49 | preserveFileTimestamps = false
50 | reproducibleFileOrder = true
51 | }
52 |
53 | afterEvaluate {
54 | if (it.plugins.hasPlugin("com.modrinth.minotaur")) {
55 | modrinth {
56 | token = System.getenv("MODRINTH_TOKEN") // This is the default. Remember to have the MODRINTH_TOKEN environment variable set or else this will fail, or set it to whatever you want - just make sure it stays private!
57 | projectId = "raknetify" // This can be the project ID or the slug. Either will work!
58 | // versionNumber = project.version + "+" + project.minecraft_version // You don't need to set this manually. Will fail if Modrinth has this version already
59 | // versionName = project.version + " devbuild for " + project.minecraft_version
60 | versionType = "alpha" // This is the default -- can also be `beta` or `alpha`
61 | // uploadFile = remapShadowJar // With Loom, this MUST be set to `remapJar` instead of `jar`!
62 | gameVersions = ["1.17", "1.17.1", "1.18", "1.18.1", "1.18.2", "1.19", "1.19.1", "1.19.2", "1.19.3", "1.19.4", "1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4", "1.20.5", "1.20.6", "1.21", "1.21.1", "1.21.2", "1.21.3", "1.21.4", "1.21.5"]
63 | // loaders = ["fabric"]
64 | changelog = com.ishland.buildscript.ParseGItHubActionChangelog.getChangelog()
65 | }
66 | }
67 | }
68 |
69 | }
70 |
71 | afterEvaluate {
72 | logger.lifecycle("Version String: ${project.mod_version + '.' + getVersionSuffix()}")
73 | logger.lifecycle(com.ishland.buildscript.ParseGItHubActionChangelog.getChangelog())
74 | }
75 |
76 | String getVersionSuffix() {
77 | def stdout = new ByteArrayOutputStream()
78 | exec {
79 | commandLine 'git', 'describe', '--tags', '--dirty'
80 | standardOutput = stdout
81 | }
82 | stdout = stdout.toString().strip()
83 | def suffix = ""
84 | if (stdout.endsWith("-dirty")) {
85 | stdout = stdout.substring(0, stdout.length() - "-dirty".length())
86 | suffix = "-dirty"
87 | }
88 | if (stdout.indexOf('-') < 0) {
89 | return "0" + suffix;
90 | }
91 | def split = stdout.split('-')
92 | return split[split.length - 2] + suffix
93 | }
94 |
--------------------------------------------------------------------------------
/buildSrc/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | }
4 |
5 | sourceCompatibility = JavaVersion.VERSION_17
6 | targetCompatibility = JavaVersion.VERSION_17
7 |
8 | repositories {
9 | mavenCentral()
10 | }
11 |
12 | dependencies {
13 | // https://mvnrepository.com/artifact/com.google.code.gson/gson
14 | implementation 'com.google.code.gson:gson:+'
15 | }
16 |
17 |
18 |
--------------------------------------------------------------------------------
/buildSrc/src/main/java/com/ishland/buildscript/ParseGItHubActionChangelog.java:
--------------------------------------------------------------------------------
1 | package com.ishland.buildscript;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.JsonArray;
5 | import com.google.gson.JsonElement;
6 | import com.google.gson.JsonObject;
7 |
8 | import java.nio.file.Files;
9 | import java.nio.file.Path;
10 |
11 | public class ParseGItHubActionChangelog {
12 |
13 | public static String getChangelog() throws Throwable {
14 | final String path = System.getenv("GITHUB_EVENT_RAW_PATH");
15 | if (path == null || path.isBlank()) return "No changelog was specified. ";
16 | final JsonObject jsonObject = new Gson().fromJson(Files.readString(Path.of(path)), JsonObject.class);
17 |
18 | StringBuilder builder = new StringBuilder();
19 | builder.append("This version is uploaded automatically by GitHub Actions. \n\n")
20 | .append("Changelog: \n");
21 | final JsonArray commits = jsonObject.getAsJsonArray("commits");
22 | if (commits.isEmpty()) {
23 | builder.append("No changes detected. \n");
24 | } else {
25 | for (JsonElement commit : commits) {
26 | JsonObject object = commit.getAsJsonObject();
27 | builder.append("- ");
28 | builder.append('[').append(object.get("id").getAsString(), 0, 8).append(']')
29 | .append('(').append(object.get("url").getAsString()).append(')');
30 | builder.append(' ');
31 | builder.append(object.get("message").getAsString().split("\n")[0]);
32 | builder.append(" - ");
33 | builder.append(object.get("author").getAsJsonObject().get("name").getAsString());
34 | builder.append(" ").append('\n');
35 | }
36 | }
37 | return builder.toString();
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/bungee/build.gradle:
--------------------------------------------------------------------------------
1 | import java.nio.file.Files
2 | import java.nio.file.StandardCopyOption
3 |
4 | evaluationDependsOn(":")
5 |
6 | apply plugin: 'com.github.johnrengelman.shadow'
7 | apply plugin: 'com.modrinth.minotaur'
8 |
9 | archivesBaseName = project.archives_base_name + "-bungee"
10 | group = project.maven_group + ".bungee"
11 |
12 | repositories {
13 | ivy {
14 | url 'https://ci.md-5.net/job/'
15 | patternLayout {
16 | // artifact "[organization]/versions/[module]/builds/[revision]/downloads/[organization]-[module]-[revision](.[ext])"
17 | // https://ci.md-5.net/job/BungeeCord/1636/artifact/bootstrap/target/BungeeCord.jar
18 | artifact "[module]/[revision]/artifact/bootstrap/target/BungeeCord(.[ext])"
19 | }
20 | metadataSources {
21 | it.artifact()
22 | }
23 | }
24 | }
25 |
26 | configurations {
27 | shadowInclude
28 | }
29 |
30 | dependencies {
31 | implementation 'bungee:BungeeCord:1934'
32 | // implementation "net.md-5:bungeecord-proxy:1.+"
33 | // compileOnly 'org.projectlombok:lombok:1.18.24' // for bungeecord sources
34 |
35 | shadowInclude implementation(project(":common"))
36 | }
37 |
38 | processResources {
39 | inputs.property "version", project.version
40 |
41 | filesMatching("bungee.yml") {
42 | expand "version": project.version
43 | }
44 | }
45 |
46 | jar {
47 | exclude "META-INF/LICENSE.txt"
48 | exclude "META-INF/NOTICE.txt"
49 | from "LICENSE"
50 | }
51 |
52 | shadowJar {
53 | // dependencies {
54 | // exclude(dependency('it.unimi.dsi:fastutil'))
55 | // }
56 | exclude "META-INF/LICENSE.txt"
57 | exclude "META-INF/NOTICE.txt"
58 | minimize()
59 | archiveClassifier = "all"
60 | configurations = [ project.configurations.shadowInclude ]
61 | from "LICENSE"
62 | }
63 |
64 | assemble.dependsOn(shadowJar)
65 |
66 | tasks.withType(AbstractArchiveTask) {
67 | preserveFileTimestamps = false
68 | reproducibleFileOrder = true
69 | }
70 |
71 | modrinth {
72 | versionNumber = project.version + "+bungeecord"
73 | versionName = project.version + " devbuild for BungeeCord"
74 | uploadFile = shadowJar
75 | loaders = ["bungeecord", "waterfall"]
76 | }
77 |
78 | task("prepareRunBungee", dependsOn: shadowJar) {
79 | doFirst {
80 | Files.createDirectories(rootProject.projectDir.toPath().resolve("run-bungee").resolve("plugins"))
81 | Files.copy(shadowJar.archiveFile.getAsFile().get().toPath(), rootProject.projectDir.toPath().resolve("run-bungee").resolve("plugins").resolve("raknetify-bungee-devlaunch.jar"), StandardCopyOption.REPLACE_EXISTING)
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/bungee/src/main/java/com/ishland/raknetify/bungee/RaknetifyBungeePlugin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.bungee;
26 |
27 | import com.ishland.raknetify.bungee.connection.RakNetBungeeConnectionUtil;
28 | import com.ishland.raknetify.bungee.init.BungeeRaknetifyServer;
29 | import com.ishland.raknetify.common.data.ProtocolMultiChannelMappings;
30 | import net.md_5.bungee.api.event.PostLoginEvent;
31 | import net.md_5.bungee.api.event.ServerConnectedEvent;
32 | import net.md_5.bungee.api.plugin.Listener;
33 | import net.md_5.bungee.api.plugin.Plugin;
34 | import net.md_5.bungee.event.EventHandler;
35 |
36 | import java.util.logging.Logger;
37 |
38 | public class RaknetifyBungeePlugin extends Plugin implements Listener {
39 |
40 | public static Logger LOGGER;
41 | public static RaknetifyBungeePlugin INSTANCE;
42 |
43 | @Override
44 | public void onEnable() {
45 | super.onEnable();
46 |
47 | INSTANCE = this;
48 | LOGGER = this.getLogger();
49 |
50 | ProtocolMultiChannelMappings.init();
51 |
52 | BungeeRaknetifyServer.inject();
53 |
54 | this.getProxy().getPluginManager().registerListener(this, this);
55 | }
56 |
57 | @Override
58 | public void onDisable() {
59 | super.onDisable();
60 |
61 | BungeeRaknetifyServer.disable();
62 | }
63 |
64 | @EventHandler
65 | public void onPostLogin(PostLoginEvent evt) {
66 | RakNetBungeeConnectionUtil.onPlayerLogin(evt);
67 | }
68 |
69 | @EventHandler
70 | public void handleServerSwitch(ServerConnectedEvent evt) {
71 | RakNetBungeeConnectionUtil.handleServerSwitch(evt);
72 | }
73 |
74 | }
75 |
--------------------------------------------------------------------------------
/bungee/src/main/java/com/ishland/raknetify/bungee/connection/RakNetBungeePingUpdater.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.bungee.connection;
26 |
27 | import com.google.common.base.Preconditions;
28 | import io.netty.channel.ChannelDuplexHandler;
29 | import io.netty.channel.ChannelHandlerContext;
30 | import io.netty.util.concurrent.ScheduledFuture;
31 | import net.md_5.bungee.UserConnection;
32 | import net.md_5.bungee.api.connection.ProxiedPlayer;
33 | import network.ycc.raknet.RakNet;
34 | import network.ycc.raknet.packet.Ping;
35 |
36 | import java.util.Objects;
37 | import java.util.concurrent.TimeUnit;
38 |
39 | public class RakNetBungeePingUpdater extends ChannelDuplexHandler {
40 |
41 | public static final String NAME = "raknetify-bungee-ping-updater";
42 |
43 | private final UserConnection player;
44 |
45 | ScheduledFuture> updateTask = null;
46 |
47 | public RakNetBungeePingUpdater(UserConnection player) {
48 | this.player = Objects.requireNonNull(player);
49 | }
50 |
51 | public void handlerAdded(ChannelHandlerContext ctx) {
52 | if (ctx.channel().config() instanceof RakNet.Config config) {
53 | updateTask = ctx.channel().eventLoop().scheduleAtFixedRate(
54 | () -> player.setPing((int) ((config.getRTTNanos() + config.getRTTStdDevNanos()) / 1_000_000)),
55 | 0, 1000, TimeUnit.MILLISECONDS
56 | );
57 | }
58 | }
59 |
60 | public void handlerRemoved(ChannelHandlerContext ctx) {
61 | if (updateTask != null) {
62 | updateTask.cancel(false);
63 | updateTask = null;
64 | }
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/bungee/src/main/java/com/ishland/raknetify/bungee/connection/RakNetBungeeServerChannelEventListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.bungee.connection;
26 |
27 | import com.google.common.base.Preconditions;
28 | import com.ishland.raknetify.bungee.RaknetifyBungeePlugin;
29 | import com.ishland.raknetify.common.Constants;
30 | import com.ishland.raknetify.common.connection.SynchronizationLayer;
31 | import io.netty.channel.Channel;
32 | import io.netty.channel.ChannelDuplexHandler;
33 | import io.netty.channel.ChannelHandler;
34 | import io.netty.channel.ChannelHandlerContext;
35 | import net.md_5.bungee.api.ProxyServer;
36 | import net.md_5.bungee.protocol.DefinedPacket;
37 | import net.md_5.bungee.protocol.PacketWrapper;
38 | import net.md_5.bungee.protocol.packet.KeepAlive;
39 | import net.md_5.bungee.protocol.packet.Respawn;
40 | import network.ycc.raknet.RakNet;
41 |
42 | import java.util.Map;
43 | import java.util.concurrent.TimeUnit;
44 |
45 | public class RakNetBungeeServerChannelEventListener extends ChannelDuplexHandler {
46 |
47 | public static final String NAME = "raknetify-bungee-downstream-event-listener";
48 |
49 | private final Channel clientChannel;
50 |
51 | public RakNetBungeeServerChannelEventListener(Channel clientChannel) {
52 | Preconditions.checkArgument(clientChannel.config() instanceof RakNet.Config);
53 | this.clientChannel = clientChannel;
54 | }
55 |
56 | @Override
57 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
58 | if (msg instanceof PacketWrapper wrapper) {
59 | final DefinedPacket packet = wrapper.packet;
60 | if (packet instanceof Respawn) {
61 | clientChannel.write(SynchronizationLayer.SYNC_REQUEST_OBJECT);
62 | } else if (packet instanceof KeepAlive) {
63 | if (Constants.DEBUG) RaknetifyBungeePlugin.LOGGER.info("Received downstream keepalive, swallowing it");
64 | final long rttNanos = RakNet.config(clientChannel).getRTTNanos();
65 | // ProxyServer.getInstance().getScheduler()
66 | // .schedule(RaknetifyBungeePlugin.INSTANCE, () -> ctx.write(packet), Math.max(rttNanos - 4_000_000, 0), TimeUnit.NANOSECONDS); // reduce delay to aid scheduling overhead
67 | ctx.channel().eventLoop().schedule(() -> ctx.writeAndFlush(packet), Math.max(rttNanos - 4_000_000, 0), TimeUnit.NANOSECONDS); // reduce delay to aid scheduling overhead
68 | return; // prevent keepalive from being sent to clients
69 | }
70 | }
71 | super.channelRead(ctx, msg);
72 | }
73 |
74 | @Override
75 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
76 | super.exceptionCaught(ctx, cause);
77 | cause.printStackTrace();
78 | for (Map.Entry entry : ctx.channel().pipeline().toMap().entrySet()) {
79 | System.out.println("%s: %s".formatted(entry.getKey(), entry.getValue().getClass().getName()));
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/bungee/src/main/java/com/ishland/raknetify/bungee/connection/StripFrameHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.bungee.connection;
26 |
27 | import io.netty.buffer.ByteBuf;
28 | import io.netty.channel.ChannelHandler;
29 | import io.netty.channel.ChannelHandlerContext;
30 | import io.netty.channel.ChannelOutboundHandlerAdapter;
31 | import io.netty.channel.ChannelPromise;
32 | import net.md_5.bungee.protocol.DefinedPacket;
33 |
34 | @ChannelHandler.Sharable
35 | public class StripFrameHandler extends ChannelOutboundHandlerAdapter {
36 |
37 | public static final String NAME = "raknetify-bungee-strip-frame";
38 |
39 | public static final StripFrameHandler INSTANCE = new StripFrameHandler();
40 |
41 | private StripFrameHandler() {
42 | }
43 |
44 | @Override
45 | public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
46 | if (msg instanceof ByteBuf buf) {
47 | DefinedPacket.readVarInt(buf);
48 | ctx.write(buf.slice(), promise);
49 | return;
50 | }
51 | super.write(ctx, msg, promise);
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/bungee/src/main/java/com/ishland/raknetify/bungee/init/InjectedSet.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.bungee.init;
26 |
27 | import com.google.common.collect.ForwardingSet;
28 | import com.ishland.raknetify.bungee.RaknetifyBungeePlugin;
29 | import io.netty.channel.Channel;
30 | import net.md_5.bungee.BungeeCord;
31 | import net.md_5.bungee.api.ProxyServer;
32 |
33 | import java.util.Set;
34 | import java.util.concurrent.TimeUnit;
35 |
36 | public class InjectedSet extends ForwardingSet {
37 |
38 | private final Set delegate;
39 |
40 | public InjectedSet(Set delegate) {
41 | this.delegate = delegate;
42 | }
43 |
44 | @Override
45 | public boolean add(Channel element) {
46 | ProxyServer.getInstance().getScheduler().schedule(
47 | RaknetifyBungeePlugin.INSTANCE,
48 | () -> BungeeRaknetifyServer.injectChannel((BungeeCord) ProxyServer.getInstance(), element, false),
49 | 100, TimeUnit.MILLISECONDS);
50 |
51 | return super.add(element);
52 | }
53 |
54 | @Override
55 | public void clear() {
56 | BungeeRaknetifyServer.stopAll();
57 |
58 | super.clear();
59 | }
60 |
61 | @Override
62 | protected Set delegate() {
63 | return this.delegate;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/bungee/src/main/resources/bungee.yml:
--------------------------------------------------------------------------------
1 | #
2 | # This file is a part of the Raknetify project, licensed under MIT.
3 | #
4 | # Copyright (c) 2022-2025 ishland
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | # THE SOFTWARE.
23 | #
24 |
25 | name: raknetify
26 | main: com.ishland.raknetify.bungee.RaknetifyBungeePlugin
27 | version: ${version}
28 | author: ishland
29 | softDepends:
30 | - ViaVersion
31 |
--------------------------------------------------------------------------------
/common/build.gradle:
--------------------------------------------------------------------------------
1 | dependencies {
2 | api("com.github.RelativityMC.netty-raknet:netty-raknet-common") {
3 | transitive = false
4 | }
5 | api("com.github.RelativityMC.netty-raknet:netty-raknet-client")
6 | api("com.github.RelativityMC.netty-raknet:netty-raknet-server")
7 | api("org.apache.commons:commons-math3:3.6.1")
8 |
9 | //noinspection GradlePackageUpdate
10 | compileOnly("io.netty:netty-all:4.1.25.Final")
11 |
12 | compileOnly("com.google.code.gson:gson:2.9.0")
13 | compileOnly("com.google.guava:guava:31.1-jre")
14 | }
15 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ishland/raknetify/common/Constants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.common;
26 |
27 | public class Constants {
28 |
29 | public static final boolean DEBUG = Boolean.getBoolean("raknetify.debug");
30 |
31 | public static final String RAKNET_PREFIX = "raknet;";
32 | public static final String RAKNET_LARGE_MTU_PREFIX = "raknetl;";
33 | public static final int RAKNET_PING_PACKET_ID = 0xFA;
34 | public static final int RAKNET_GAME_PACKET_ID = 0xFD;
35 | public static final int RAKNET_STREAMING_COMPRESSION_PACKET_ID = 0xED;
36 | public static final int RAKNET_STREAMING_COMPRESSION_HANDSHAKE_PACKET_ID = 0xEC;
37 | public static final int RAKNET_SYNC_PACKET_ID = 0xFC;
38 | public static final int RAKNET_METRICS_SYNC_PACKET_ID = 0xFB;
39 | public static final int MAX_QUEUED_SIZE = 256 * 1024 * 1024;
40 | public static final int DEFAULT_MTU = 1400;
41 | public static final int LARGE_MTU = 8192;
42 | public static final int MAX_PENDING_FRAME_SETS = 512;
43 | public static final int DEFAULT_PENDING_FRAME_SETS = 4;
44 | public static final int[] SYNC_IGNORE_CHANNELS = new int[] {1};
45 |
46 | private Constants() {
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ishland/raknetify/common/connection/ByteBufCopyDecoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.common.connection;
26 |
27 | import io.netty.buffer.ByteBuf;
28 | import io.netty.channel.ChannelHandlerContext;
29 | import io.netty.channel.ChannelInboundHandlerAdapter;
30 |
31 | public class ByteBufCopyDecoder extends ChannelInboundHandlerAdapter {
32 |
33 | public static final String NAME = "raknetify-byte-buf-copy-decoder";
34 |
35 | @Override
36 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
37 | if (msg instanceof ByteBuf buf && !buf.hasMemoryAddress()) {
38 | ctx.fireChannelRead(ctx.alloc().directBuffer(buf.readableBytes()).writeBytes(buf));
39 | buf.release();
40 | return;
41 | }
42 | super.channelRead(ctx, msg);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ishland/raknetify/common/connection/FrameDataBlocker.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.common.connection;
26 |
27 | import io.netty.channel.ChannelHandlerContext;
28 | import io.netty.channel.ChannelInboundHandlerAdapter;
29 | import network.ycc.raknet.frame.FrameData;
30 |
31 | public class FrameDataBlocker extends ChannelInboundHandlerAdapter {
32 |
33 | private static final boolean printBlockedFrames = Boolean.getBoolean("raknetify.printBlockedFrames");
34 |
35 | @Override
36 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
37 | if (msg instanceof FrameData data) {
38 | if (printBlockedFrames) System.out.println("Blocked %s".formatted(msg));
39 | data.release();
40 | return;
41 | }
42 | ctx.fireChannelRead(msg);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ishland/raknetify/common/connection/NoFlush.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.common.connection;
26 |
27 | import io.netty.channel.ChannelDuplexHandler;
28 | import io.netty.channel.ChannelHandlerContext;
29 |
30 | public class NoFlush extends ChannelDuplexHandler {
31 |
32 | @Override
33 | public void flush(ChannelHandlerContext ctx) {
34 | // no-op
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ishland/raknetify/common/connection/PacketEncryptionManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.common.connection;
26 |
27 | import io.netty.buffer.ByteBuf;
28 |
29 | import javax.crypto.Cipher;
30 | import java.security.GeneralSecurityException;
31 |
32 | // TODO [VanillaCopy] from fabric
33 | public class PacketEncryptionManager {
34 | private final Cipher cipher;
35 | private byte[] conversionBuffer = new byte[0];
36 | private byte[] encryptionBuffer = new byte[0];
37 |
38 | protected PacketEncryptionManager(Cipher cipher) {
39 | this.cipher = cipher;
40 | }
41 |
42 | private byte[] toByteArray(ByteBuf buf) {
43 | int i = buf.readableBytes();
44 | if (this.conversionBuffer.length < i) {
45 | this.conversionBuffer = new byte[i];
46 | }
47 |
48 | buf.readBytes(this.conversionBuffer, 0, i);
49 | return this.conversionBuffer;
50 | }
51 |
52 | public void doWork(ByteBuf buf, ByteBuf result) throws GeneralSecurityException {
53 | int i = buf.readableBytes();
54 | byte[] bs = this.toByteArray(buf);
55 | int outputSize = this.cipher.getOutputSize(i);
56 | if (this.encryptionBuffer.length < outputSize) {
57 | this.encryptionBuffer = new byte[outputSize];
58 | }
59 |
60 | result.writeBytes(this.encryptionBuffer, 0, this.cipher.doFinal(bs, 0, i, this.encryptionBuffer));
61 | }
62 | }
63 |
64 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ishland/raknetify/common/connection/multichannel/CustomPayloadChannel.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.common.connection.multichannel;
26 |
27 | import com.ishland.raknetify.common.Constants;
28 | import com.ishland.raknetify.common.connection.RakNetSimpleMultiChannelCodec;
29 | import com.ishland.raknetify.common.util.MathUtil;
30 | import io.netty.buffer.ByteBuf;
31 | import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
32 |
33 | import java.util.Objects;
34 | import java.util.function.IntPredicate;
35 |
36 | public class CustomPayloadChannel {
37 |
38 | public static final Object2IntOpenHashMap identifier2channel;
39 |
40 | static {
41 | // See .fabric.common.connection.RakNetMultiChannel
42 |
43 | identifier2channel = new Object2IntOpenHashMap<>();
44 | identifier2channel.defaultReturnValue(0);
45 | identifier2channel.put("porting_lib:extra_data_entity_spawn", 2);
46 | identifier2channel.put("porting_lib:extra_entity_spawn_data", 2); // https://github.com/Fabricators-of-Create/Porting-Lib/commit/4b0cd845731f89eafd9fb39e13e1a7d87f5e14a4
47 | }
48 |
49 | public static class OverrideHandler implements RakNetSimpleMultiChannelCodec.OverrideHandler {
50 |
51 | private final IntPredicate isCustomPayload;
52 |
53 | public OverrideHandler(IntPredicate isCustomPayload) {
54 | this.isCustomPayload = Objects.requireNonNull(isCustomPayload);
55 | }
56 |
57 | @Override
58 | public int getChannelOverride(ByteBuf origBuf, boolean suppressWarning) {
59 | ByteBuf buf = origBuf.slice();
60 | final int packetId = MathUtil.readVarInt(buf);
61 | if (isCustomPayload.test(packetId)) {
62 | final String identifier = MathUtil.readString(buf); // we assume modern custom payloads
63 | if (Constants.DEBUG) System.out.println("Raknetify: Handling custom payload: " + identifier);
64 | return identifier2channel.getInt(identifier);
65 | } else {
66 | return 0;
67 | }
68 | }
69 |
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ishland/raknetify/common/data/ProtocolMultiChannelMappings.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.common.data;
26 |
27 | import com.google.gson.Gson;
28 | import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
29 | import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
30 | import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
31 |
32 | import java.io.IOException;
33 | import java.io.InputStream;
34 | import java.io.InputStreamReader;
35 |
36 | public class ProtocolMultiChannelMappings {
37 |
38 | public static final ProtocolMultiChannelMappings INSTANCE;
39 |
40 | static {
41 | final InputStream resource = ProtocolMultiChannelMappings.class.getClassLoader().getResourceAsStream("raknetify-channel-mappings.json");
42 | if (resource == null) {
43 | System.err.println("Raknetify: Failed to load raknetify channel mappings");
44 | INSTANCE = new ProtocolMultiChannelMappings();
45 | } else {
46 | ProtocolMultiChannelMappings read = new ProtocolMultiChannelMappings();
47 | try (var in = resource;
48 | var reader = new InputStreamReader(resource)) {
49 | final Gson gson = new Gson();
50 | read = gson.fromJson(reader, ProtocolMultiChannelMappings.class);
51 | } catch (IOException e) {
52 | System.err.println("Raknetify: Failed to load raknetify channel mappings");
53 | e.printStackTrace();
54 | }
55 | INSTANCE = read;
56 | }
57 | }
58 |
59 | public static void init() {
60 | }
61 |
62 | public Int2ObjectArrayMap mappings = new Int2ObjectArrayMap<>();
63 |
64 | public static class VersionMapping {
65 | public Int2IntArrayMap s2c = new Int2IntArrayMap();
66 | public Int2IntArrayMap c2s = new Int2IntArrayMap();
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ishland/raknetify/common/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.common;
26 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ishland/raknetify/common/util/MathUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.common.util;
26 |
27 | import com.google.common.base.Charsets;
28 | import io.netty.buffer.ByteBuf;
29 |
30 | import java.text.CharacterIterator;
31 | import java.text.StringCharacterIterator;
32 |
33 | public class MathUtil {
34 |
35 | public static String humanReadableByteCountBin(long bytes) {
36 | long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
37 | if (absB < 1024) {
38 | return bytes + " B";
39 | }
40 | long value = absB;
41 | CharacterIterator ci = new StringCharacterIterator("KMGTPE");
42 | for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10) {
43 | value >>= 10;
44 | ci.next();
45 | }
46 | value *= Long.signum(bytes);
47 | return String.format("%.2f %ciB", value / 1024.0, ci.current());
48 | }
49 |
50 | public static int readVarInt(ByteBuf buf) {
51 | // TODO [VanillaCopy]
52 | int i = 0;
53 | int j = 0;
54 |
55 | byte b;
56 | do {
57 | b = buf.readByte();
58 | i |= (b & 127) << j++ * 7;
59 | if (j > 5) {
60 | throw new RuntimeException("VarInt too big");
61 | }
62 | } while ((b & 128) == 128);
63 |
64 | return i;
65 | }
66 |
67 | public static String readString(ByteBuf buf) {
68 | return readString(buf, Short.MAX_VALUE);
69 | }
70 |
71 | public static String readString(ByteBuf buf, int maxLen) {
72 | // Copied from BungeeCord
73 | int len = readVarInt(buf);
74 | if (len > maxLen * 3) {
75 | throw new IllegalArgumentException("Cannot receive string longer than " + maxLen * 3 + " (got " + len + " bytes)");
76 | }
77 |
78 | String s = buf.toString(buf.readerIndex(), len, Charsets.UTF_8);
79 | buf.readerIndex(buf.readerIndex() + len);
80 |
81 | if (s.length() > maxLen) {
82 | throw new IllegalArgumentException("Cannot receive string longer than " + maxLen + " (got " + s.length() + " characters)");
83 | }
84 |
85 | return s;
86 | }
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ishland/raknetify/common/util/PrefixUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.common.util;
26 |
27 | import com.ishland.raknetify.common.Constants;
28 |
29 | public class PrefixUtil {
30 |
31 | public static Info getInfo(String address) {
32 | if (address.startsWith(Constants.RAKNET_PREFIX)) {
33 | return new Info(true, address.substring(Constants.RAKNET_PREFIX.length()), false);
34 | } else if (address.startsWith(Constants.RAKNET_LARGE_MTU_PREFIX)) {
35 | return new Info(true, address.substring(Constants.RAKNET_LARGE_MTU_PREFIX.length()), true);
36 | } else {
37 | return new Info(false, address, false);
38 | }
39 | }
40 |
41 | public record Info(boolean useRakNet, String stripped, boolean largeMTU) {
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ishland/raknetify/common/util/ReflectionUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.common.util;
26 |
27 | import java.lang.reflect.Field;
28 | import java.lang.reflect.Method;
29 |
30 | public class ReflectionUtil {
31 |
32 | public static Field accessible(Field field) {
33 | field.setAccessible(true);
34 | return field;
35 | }
36 |
37 | public static Method accessible(Method method) {
38 | method.setAccessible(true);
39 | return method;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/common/src/main/java/com/ishland/raknetify/common/util/ThreadLocalUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.common.util;
26 |
27 | public class ThreadLocalUtil {
28 |
29 | private ThreadLocalUtil() {
30 | }
31 |
32 | private static final ThreadLocal initializingRaknet = ThreadLocal.withInitial(() -> false);
33 | private static final ThreadLocal initializingRaknetLargeMTU = ThreadLocal.withInitial(() -> false);
34 |
35 | public static void setInitializingRaknet(boolean value) {
36 | initializingRaknet.set(value);
37 | }
38 |
39 | public static void setInitializingRaknetLargeMTU(boolean value) {
40 | initializingRaknetLargeMTU.set(value);
41 | }
42 |
43 | public static boolean isInitializingRaknet() {
44 | return initializingRaknet.get();
45 | }
46 |
47 | public static boolean isInitializingRaknetLargeMTU() {
48 | return initializingRaknetLargeMTU.get();
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/fabric/build.gradle:
--------------------------------------------------------------------------------
1 | evaluationDependsOn(":")
2 |
3 | apply plugin: 'fabric-loom'
4 | apply plugin: 'com.github.johnrengelman.shadow'
5 | apply plugin: 'com.modrinth.minotaur'
6 | apply plugin: 'com.matthewprenger.cursegradle'
7 |
8 | archivesBaseName = project.archives_base_name + "-fabric"
9 | group = project.maven_group + ".fabric"
10 |
11 | configurations {
12 | shadowInclude
13 | }
14 |
15 | dependencies {
16 | // To change the versions see the gradle.properties file
17 | minecraft "com.mojang:minecraft:${project.minecraft_version}"
18 | mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
19 | modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
20 |
21 | shadowInclude implementation(project(":common"))
22 |
23 | // Fabric API. This is technically optional, but you probably want it anyway.
24 | // modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
25 | }
26 |
27 | processResources {
28 | inputs.property "version", project.version
29 |
30 | filesMatching("fabric.mod.json") {
31 | expand "version": project.version
32 | }
33 | }
34 |
35 | tasks.withType(JavaCompile).configureEach {
36 | // Minecraft 1.18 (1.18-pre2) upwards uses Java 17.
37 | it.options.release = 17
38 | }
39 |
40 | java {
41 | // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
42 | // if it is present.
43 | // If you remove this line, sources will not be generated.
44 | withSourcesJar()
45 | }
46 |
47 | loom {
48 | accessWidenerPath = file("src/main/resources/raknetify-fabric.accesswidener")
49 | runs {
50 | server {
51 | vmArgs "-Draknetify.debug=true", "-Dio.netty.leakDetection.level=advanced"
52 | ideConfigGenerated(true)
53 | }
54 | client {
55 | vmArgs "-Draknetify.debug=true", "-Dio.netty.leakDetection.level=advanced"
56 | ideConfigGenerated(true)
57 | }
58 | }
59 | }
60 |
61 | jar {
62 | exclude "META-INF/LICENSE.txt"
63 | exclude "META-INF/NOTICE.txt"
64 | from "../LICENSE"
65 | }
66 |
67 | shadowJar {
68 | dependencies {
69 | exclude(dependency('it.unimi.dsi:fastutil'))
70 | }
71 | exclude "META-INF/LICENSE.txt"
72 | exclude "META-INF/NOTICE.txt"
73 | minimize()
74 | archiveClassifier = "all-dev"
75 | configurations = [ project.configurations.shadowInclude ]
76 | from "../LICENSE"
77 | }
78 |
79 | //noinspection UnnecessaryQualifiedReference
80 | task("remapShadowJar", type: net.fabricmc.loom.task.RemapJarTask, dependsOn: shadowJar) {
81 | input = shadowJar.archiveFile
82 | archiveFileName = shadowJar.archiveFileName.get().replaceAll("-dev\\.jar\$", ".jar")
83 | addNestedDependencies = true
84 | }
85 |
86 | assemble.dependsOn(remapShadowJar)
87 |
88 | afterEvaluate {
89 | migrateMappings.configure {
90 | outputDir = project.file("build/remappedSrc")
91 | doLast {
92 | copy {
93 | from project.file("build/remappedSrc")
94 | into project.file("src/main/java")
95 | }
96 | }
97 | }
98 | }
99 |
100 | tasks.withType(AbstractArchiveTask) {
101 | preserveFileTimestamps = false
102 | reproducibleFileOrder = true
103 | }
104 |
105 | modrinth {
106 | versionNumber = project.version
107 | versionName = project.version + " devbuild"
108 | uploadFile = remapShadowJar
109 | loaders = ["fabric", "quilt"]
110 | }
111 |
112 | if (System.getenv("CURSEFORGE_TOKEN")) {
113 | curseforge {
114 | apiKey = System.getenv("CURSEFORGE_TOKEN")
115 | project {
116 | id = '631457'
117 | changelogType = "markdown"
118 | changelog = com.ishland.buildscript.ParseGItHubActionChangelog.getChangelog()
119 | releaseType = 'alpha'
120 |
121 | addGameVersion "1.17"
122 | addGameVersion "1.17.1"
123 | addGameVersion "1.18"
124 | addGameVersion "1.18.1"
125 | addGameVersion "1.18.2"
126 | addGameVersion "1.19"
127 | addGameVersion "1.19.1"
128 | addGameVersion "1.19.2"
129 | addGameVersion "1.19.3"
130 | addGameVersion "1.19.4"
131 | addGameVersion "1.20"
132 | addGameVersion "1.20.1"
133 | addGameVersion "1.20.2"
134 | addGameVersion "1.20.3"
135 | addGameVersion "1.20.4"
136 | addGameVersion "1.20.5"
137 | addGameVersion "1.20.6"
138 | addGameVersion "1.21"
139 | addGameVersion "1.21.1"
140 | addGameVersion "1.21.2"
141 | addGameVersion "1.21.3"
142 | addGameVersion "1.21.4"
143 | addGameVersion "1.21.5"
144 | addGameVersion "Fabric"
145 | addGameVersion "Java 17"
146 | addGameVersion "Java 18"
147 | addGameVersion "Java 19"
148 | addGameVersion "Java 20"
149 | addGameVersion "Java 21"
150 | addGameVersion "Java 22"
151 |
152 | mainArtifact(remapShadowJar) {
153 | displayName = project.version + " devbuild"
154 | }
155 | }
156 | options {
157 | forgeGradleIntegration = false
158 | }
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/common/compat/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.common.compat;
26 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/common/connection/MultiChannellingPacketCapture.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.common.connection;
26 |
27 | import com.ishland.raknetify.common.connection.RakNetSimpleMultiChannelCodec;
28 | import com.ishland.raknetify.common.connection.multichannel.CustomPayloadChannel;
29 | import io.netty.buffer.ByteBuf;
30 | import io.netty.channel.ChannelHandler;
31 | import io.netty.channel.ChannelHandlerContext;
32 | import io.netty.channel.ChannelOutboundHandlerAdapter;
33 | import io.netty.channel.ChannelPromise;
34 | import net.minecraft.network.packet.c2s.common.CustomPayloadC2SPacket;
35 | import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket;
36 |
37 | @ChannelHandler.Sharable
38 | public class MultiChannellingPacketCapture extends ChannelOutboundHandlerAdapter {
39 |
40 | private Class> packetClass = null;
41 |
42 | @Override
43 | public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
44 | this.packetClass = msg.getClass();
45 | try {
46 | ctx.write(msg, promise);
47 | } finally {
48 | this.packetClass = null;
49 | }
50 | }
51 |
52 | public Class> getPacketClass() {
53 | return this.packetClass;
54 | }
55 |
56 | public void setPacketClass(Class> packetClass) {
57 | this.packetClass = packetClass;
58 | }
59 |
60 | public RakNetSimpleMultiChannelCodec.OverrideHandler getCaptureBasedHandler() {
61 | return new CaptureBasedHandler();
62 | }
63 |
64 | public RakNetSimpleMultiChannelCodec.OverrideHandler getCustomPayloadHandler() {
65 | return new CustomPayloadChannel.OverrideHandler(value -> packetClass == CustomPayloadS2CPacket.class || packetClass == CustomPayloadC2SPacket.class);
66 | }
67 |
68 | private class CaptureBasedHandler implements RakNetSimpleMultiChannelCodec.OverrideHandler {
69 |
70 | @Override
71 | public int getChannelOverride(ByteBuf buf, boolean suppressWarning) {
72 | return RakNetMultiChannel.getPacketChannelOverride(packetClass, suppressWarning);
73 | }
74 |
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/common/connection/RakNetClientConnectionUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.common.connection;
26 |
27 | import com.ishland.raknetify.common.util.ThreadLocalUtil;
28 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
29 | import io.netty.channel.ChannelFuture;
30 | import net.minecraft.network.ClientConnection;
31 |
32 | import java.net.InetSocketAddress;
33 |
34 | public class RakNetClientConnectionUtil {
35 |
36 | private RakNetClientConnectionUtil() {
37 | }
38 |
39 | public static ClientConnection connect(InetSocketAddress address, boolean useEpoll, boolean largeMTU, Operation original, boolean hasPerformanceLog) {
40 | System.out.println("aaa");
41 | try {
42 | ThreadLocalUtil.setInitializingRaknet(true);
43 | ThreadLocalUtil.setInitializingRaknetLargeMTU(largeMTU);
44 | if (hasPerformanceLog) {
45 | return original.call(address, useEpoll, null);
46 | } else {
47 | return original.call(address, useEpoll);
48 | }
49 | } finally {
50 | ThreadLocalUtil.setInitializingRaknet(false);
51 | ThreadLocalUtil.setInitializingRaknetLargeMTU(false);
52 | }
53 | }
54 |
55 | public static ChannelFuture connect(InetSocketAddress address, boolean useEpoll, boolean largeMTU, ClientConnection connection) {
56 | System.out.println("aaaa");
57 | try {
58 | ThreadLocalUtil.setInitializingRaknet(true);
59 | ThreadLocalUtil.setInitializingRaknetLargeMTU(largeMTU);
60 | return ClientConnection.connect(address, useEpoll, connection);
61 | } finally {
62 | ThreadLocalUtil.setInitializingRaknet(false);
63 | ThreadLocalUtil.setInitializingRaknetLargeMTU(false);
64 | }
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/common/connection/RakNetCompressionCompatibilityHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.common.connection;
26 |
27 | import io.netty.channel.ChannelDuplexHandler;
28 | import io.netty.channel.ChannelHandlerContext;
29 | import io.netty.channel.ChannelPromise;
30 | import net.minecraft.network.packet.s2c.login.LoginCompressionS2CPacket;
31 |
32 | public class RakNetCompressionCompatibilityHandler extends ChannelDuplexHandler {
33 |
34 | @Override
35 | public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
36 | if (msg instanceof LoginCompressionS2CPacket) {
37 | promise.trySuccess();
38 | ctx.write(msg);
39 | ctx.pipeline().remove(this);
40 | return;
41 | }
42 | super.write(ctx, msg, promise);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/common/connection/RakNetFabricChannelEventListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.common.connection;
26 |
27 | import com.ishland.raknetify.common.connection.RakNetSimpleMultiChannelCodec;
28 | import com.ishland.raknetify.common.connection.SynchronizationLayer;
29 | import com.ishland.raknetify.fabric.mixin.RaknetifyFabricMixinPlugin;
30 | import io.netty.channel.ChannelDuplexHandler;
31 | import io.netty.channel.ChannelHandlerContext;
32 | import io.netty.channel.ChannelPromise;
33 | import net.minecraft.network.handler.NetworkStateTransitions;
34 | import net.minecraft.network.packet.c2s.play.AcknowledgeReconfigurationC2SPacket;
35 | import net.minecraft.network.packet.s2c.play.CommandTreeS2CPacket;
36 | import net.minecraft.network.packet.s2c.play.EnterReconfigurationS2CPacket;
37 | import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
38 | import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket;
39 |
40 | public class RakNetFabricChannelEventListener extends ChannelDuplexHandler {
41 |
42 | public static final String NAME = "raknetify-fabric-event-listener";
43 |
44 | private static final boolean isReconfigurationSupported;
45 |
46 | static {
47 | boolean isReconfigurationSupported0;
48 | try {
49 | EnterReconfigurationS2CPacket.class.getName();
50 | isReconfigurationSupported0 = true;
51 | } catch (NoClassDefFoundError e) {
52 | isReconfigurationSupported0 = false;
53 | }
54 | isReconfigurationSupported = isReconfigurationSupported0;
55 | }
56 |
57 | @Override
58 | public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
59 | if (msg instanceof PlayerRespawnS2CPacket || msg instanceof GameJoinS2CPacket) {
60 | ctx.write(SynchronizationLayer.SYNC_REQUEST_OBJECT);
61 | }
62 | if (isReconfigurationSupported) {
63 | if (msg instanceof EnterReconfigurationS2CPacket || msg instanceof AcknowledgeReconfigurationC2SPacket) {
64 | ctx.write(SynchronizationLayer.SYNC_REQUEST_OBJECT);
65 | }
66 | }
67 | if (msg instanceof CommandTreeS2CPacket) {
68 | ctx.write(RakNetSimpleMultiChannelCodec.SIGNAL_START_MULTICHANNEL);
69 | }
70 | if (RaknetifyFabricMixinPlugin.AFTER_1_20_5) {
71 | if (msg instanceof NetworkStateTransitions.DecoderTransitioner || msg instanceof NetworkStateTransitions.EncoderTransitioner) {
72 | ctx.write(RakNetNetworkTransitionUtil.handleTransition(msg), promise);
73 | return;
74 | }
75 | }
76 | super.write(ctx, msg, promise);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/common/connection/RakNetFabricConnectionUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.common.connection;
26 |
27 | import com.ishland.raknetify.common.Constants;
28 | import com.ishland.raknetify.common.connection.MultiChannelingStreamingCompression;
29 | import com.ishland.raknetify.common.connection.RakNetConnectionUtil;
30 | import com.ishland.raknetify.common.connection.RakNetSimpleMultiChannelCodec;
31 | import com.ishland.raknetify.fabric.common.compat.viafabric.ViaFabricCompatInjector;
32 | import io.netty.channel.Channel;
33 | import io.netty.channel.ChannelDuplexHandler;
34 | import io.netty.channel.ChannelHandler;
35 | import io.netty.channel.ChannelHandlerContext;
36 | import io.netty.channel.ChannelPipeline;
37 | import network.ycc.raknet.RakNet;
38 |
39 | public class RakNetFabricConnectionUtil {
40 |
41 | public static final String NAME_RAKNETIFY_MULTI_CHANNEL_PACKET_CATURE = "raknetify-multi-channel-packet-cature";
42 |
43 | private RakNetFabricConnectionUtil() {
44 | }
45 |
46 | public static void initChannel(Channel channel) {
47 | if (channel.config() instanceof RakNet.Config) {
48 | RakNetConnectionUtil.initChannel(channel);
49 | channel.pipeline().addAfter(MultiChannelingStreamingCompression.NAME, RakNetSimpleMultiChannelCodec.NAME, new RakNetSimpleMultiChannelCodec(Constants.RAKNET_GAME_PACKET_ID));
50 | }
51 | }
52 |
53 | public static void postInitChannel(Channel channel, boolean isClientSide) {
54 | if (channel.config() instanceof RakNet.Config) {
55 | ViaFabricCompatInjector.inject(channel, isClientSide);
56 | channel.pipeline().replace("timeout", "timeout", new ChannelDuplexHandler()); // no-op
57 | channel.pipeline().replace("splitter", "splitter", new ChannelDuplexHandler()); // no-op
58 | channel.pipeline().replace("prepender", "prepender", new ChannelDuplexHandler()); // no-op
59 | final MultiChannellingPacketCapture handler = new MultiChannellingPacketCapture();
60 | channel.pipeline().addLast(NAME_RAKNETIFY_MULTI_CHANNEL_PACKET_CATURE, handler);
61 | onPipelineReorder(channel.pipeline());
62 | channel.pipeline().get(RakNetSimpleMultiChannelCodec.class)
63 | .addHandler(handler.getCustomPayloadHandler())
64 | .addHandler(handler.getCaptureBasedHandler());
65 | channel.pipeline().addLast("raknetify-handle-compression-compatibility", new RakNetCompressionCompatibilityHandler());
66 | channel.pipeline().addBefore("packet_handler", RakNetFabricChannelEventListener.NAME, new RakNetFabricChannelEventListener());
67 | }
68 | }
69 |
70 | static void onPipelineReorder(ChannelPipeline pipeline) {
71 | if (pipeline.get("encoder") == null) {
72 | // System.out.println("Reordering failed: no encoder");
73 | return;
74 | }
75 | // System.out.println("Reordering");
76 | ChannelHandler handler = pipeline.remove(RakNetFabricConnectionUtil.NAME_RAKNETIFY_MULTI_CHANNEL_PACKET_CATURE);
77 | if (handler != null) {
78 | pipeline.addAfter("encoder", RakNetFabricConnectionUtil.NAME_RAKNETIFY_MULTI_CHANNEL_PACKET_CATURE, handler);
79 | }
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/common/connection/RakNetNetworkTransitionUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.common.connection;
26 |
27 | import net.minecraft.network.handler.NetworkStateTransitions;
28 |
29 | public class RakNetNetworkTransitionUtil {
30 |
31 | static Object handleTransition(Object msg) {
32 | if (msg instanceof NetworkStateTransitions.DecoderTransitioner transitioner) {
33 | return transitioner.andThen(context -> RakNetFabricConnectionUtil.onPipelineReorder(context.pipeline()));
34 | } else if (msg instanceof NetworkStateTransitions.EncoderTransitioner transitioner) {
35 | return transitioner.andThen(context -> RakNetFabricConnectionUtil.onPipelineReorder(context.pipeline()));
36 | }
37 | return msg;
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/common/connection/encryption/PacketEncryptionManagerInterface.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.common.connection.encryption;
26 |
27 | import io.netty.channel.ChannelHandlerContext;
28 |
29 | public interface PacketEncryptionManagerInterface {
30 |
31 | void setContext(ChannelHandlerContext ctx);
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/common/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.common;
26 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/common/quirks/ClientHungerManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.common.quirks;
26 |
27 | import net.minecraft.component.type.FoodComponent;
28 | import net.minecraft.entity.player.HungerManager;
29 | import net.minecraft.nbt.NbtCompound;
30 |
31 | public class ClientHungerManager extends HungerManager {
32 |
33 | public static ClientHungerManager from(HungerManager hungerManager) {
34 | ClientHungerManager clientHungerManager = new ClientHungerManager();
35 | NbtCompound compound = new NbtCompound();
36 | hungerManager.writeNbt(compound);
37 | clientHungerManager.readNbt(compound);
38 | return clientHungerManager;
39 | }
40 |
41 | public void add(int food, float saturationModifier) {
42 | // nop
43 | }
44 |
45 | public void eat(FoodComponent foodComponent) {
46 | // nop
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/common/util/FieldSignatureParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.common.util;
26 |
27 | import org.objectweb.asm.Type;
28 | import org.objectweb.asm.signature.SignatureReader;
29 | import org.objectweb.asm.signature.SignatureVisitor;
30 | import org.spongepowered.asm.util.asm.ASM;
31 |
32 | import java.util.ArrayList;
33 | import java.util.List;
34 |
35 | public class FieldSignatureParser extends SignatureVisitor {
36 |
37 | private final List results = new ArrayList<>();
38 |
39 | private FieldSignatureParser() {
40 | super(ASM.API_VERSION);
41 | }
42 |
43 | public static List parse(String signature) {
44 | if (signature == null || signature.isEmpty()) {
45 | return List.of();
46 | }
47 | FieldSignatureParser parser = new FieldSignatureParser();
48 | new SignatureReader(signature).acceptType(parser);
49 | return parser.results;
50 | }
51 |
52 | @Override
53 | public void visitClassType(String name) {
54 | results.add(Type.getObjectType(name));
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/common/util/NetworkStates.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.common.util;
26 |
27 | import net.minecraft.network.NetworkPhase;
28 |
29 | public class NetworkStates {
30 |
31 | public static String getName(NetworkPhase state) {
32 | return switch (state) {
33 | case HANDSHAKING -> "HANDSHAKING";
34 | case PLAY -> "PLAY";
35 | case STATUS -> "STATUS";
36 | case LOGIN -> "LOGIN";
37 | default -> state.toString();
38 | };
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/access/IClientConnection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.access;
26 |
27 | import io.netty.channel.Channel;
28 | import net.minecraft.network.ClientConnection;
29 | import org.spongepowered.asm.mixin.Mixin;
30 | import org.spongepowered.asm.mixin.gen.Accessor;
31 |
32 | @Mixin(ClientConnection.class)
33 | public interface IClientConnection {
34 |
35 | @Accessor
36 | Channel getChannel();
37 |
38 | @Accessor
39 | void setEncrypted(boolean encrypted);
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/access/IClientPlayNetworkHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.access;
26 |
27 | import net.minecraft.client.network.ClientPlayNetworkHandler;
28 | import net.minecraft.network.ClientConnection;
29 | import org.spongepowered.asm.mixin.Mixin;
30 | import org.spongepowered.asm.mixin.gen.Accessor;
31 |
32 | @Mixin(ClientPlayNetworkHandler.class)
33 | public interface IClientPlayNetworkHandler {
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/access/INetworkState1_20_4.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.access;
26 |
27 | import net.minecraft.network.NetworkPhase;
28 | import net.minecraft.network.NetworkSide;
29 | import org.spongepowered.asm.mixin.Dynamic;
30 | import org.spongepowered.asm.mixin.Mixin;
31 | import org.spongepowered.asm.mixin.Pseudo;
32 | import org.spongepowered.asm.mixin.gen.Accessor;
33 |
34 | import java.util.Map;
35 |
36 | @Pseudo
37 | @Mixin(targets = "net/minecraft/class_2539")
38 | public interface INetworkState1_20_4 {
39 |
40 | @Dynamic
41 | @Accessor(value = "field_20595", remap = false)
42 | Map getPacketHandlers();
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/access/INetworkStateInternalPacketHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.access;
26 |
27 | import it.unimi.dsi.fastutil.objects.Object2IntMap;
28 | import net.minecraft.network.NetworkPhase;
29 | import net.minecraft.network.packet.Packet;
30 | import org.spongepowered.asm.mixin.Mixin;
31 | import org.spongepowered.asm.mixin.gen.Accessor;
32 |
33 | @Mixin(targets = "net/minecraft/class_2539$class_4532")
34 | public interface INetworkStateInternalPacketHandler {
35 |
36 | @Accessor(value = "field_20596")
37 | Object2IntMap>> getPacketIds();
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/access/IPacketCodecDispatcher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.access;
26 |
27 | import io.netty.buffer.ByteBuf;
28 | import net.minecraft.network.handler.PacketCodecDispatcher;
29 | import org.spongepowered.asm.mixin.Mixin;
30 | import org.spongepowered.asm.mixin.gen.Accessor;
31 |
32 | import java.util.List;
33 |
34 | @Mixin(PacketCodecDispatcher.class)
35 | public interface IPacketCodecDispatcher {
36 |
37 | @Accessor
38 | List> getPacketTypes();
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/access/IPacketCodecDispatcherPacketType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.access;
26 |
27 | import net.minecraft.network.handler.PacketCodecDispatcher;
28 | import org.spongepowered.asm.mixin.Mixin;
29 |
30 | @Mixin(PacketCodecDispatcher.PacketType.class)
31 | public interface IPacketCodecDispatcherPacketType {
32 | }
33 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/access/IPacketEncryptionManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.access;
26 |
27 | import io.netty.buffer.ByteBuf;
28 | import io.netty.channel.ChannelHandlerContext;
29 | import net.minecraft.network.encryption.PacketEncryptionManager;
30 | import org.spongepowered.asm.mixin.Mixin;
31 | import org.spongepowered.asm.mixin.gen.Invoker;
32 |
33 | import javax.crypto.ShortBufferException;
34 |
35 | @Mixin(PacketEncryptionManager.class)
36 | public interface IPacketEncryptionManager {
37 |
38 | @Invoker
39 | ByteBuf invokeDecrypt(ChannelHandlerContext context, ByteBuf buf) throws ShortBufferException;
40 |
41 | @Invoker
42 | void invokeEncrypt(ByteBuf buf, ByteBuf result) throws ShortBufferException;
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/access/IServerPlayNetworkHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.access;
26 |
27 | import net.minecraft.server.network.ServerPlayNetworkHandler;
28 | import org.spongepowered.asm.mixin.Mixin;
29 |
30 | @Mixin(ServerPlayNetworkHandler.class)
31 | public interface IServerPlayNetworkHandler {
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/client/MixinClientPlayNetworkHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.client;
26 |
27 | import com.ishland.raknetify.common.connection.RakNetSimpleMultiChannelCodec;
28 | import com.ishland.raknetify.fabric.common.util.MultiVersionUtil;
29 | import com.ishland.raknetify.fabric.mixin.access.IClientConnection;
30 | import io.netty.channel.Channel;
31 | import net.minecraft.client.network.ClientPlayNetworkHandler;
32 | import net.minecraft.network.ClientConnection;
33 | import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
34 | import org.spongepowered.asm.mixin.Final;
35 | import org.spongepowered.asm.mixin.Mixin;
36 | import org.spongepowered.asm.mixin.Shadow;
37 | import org.spongepowered.asm.mixin.injection.At;
38 | import org.spongepowered.asm.mixin.injection.Inject;
39 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
40 |
41 | @Mixin(ClientPlayNetworkHandler.class)
42 | public class MixinClientPlayNetworkHandler {
43 |
44 | @Inject(method = "onGameJoin", at = @At("RETURN"))
45 | private void postGameJoin(GameJoinS2CPacket packet, CallbackInfo ci) {
46 | final Channel channel = ((IClientConnection) MultiVersionUtil.ClientPlayNetworkHandler$connection.get((ClientPlayNetworkHandler) (Object) this)).getChannel();
47 | if (channel == null) {
48 | //noinspection RedundantStringFormatCall
49 | System.err.println("Raknetify: Warning: %s don't have valid channel when logged in, not sending sync packet".formatted(this));
50 | return;
51 | }
52 | channel.eventLoop().execute(() -> channel.write(RakNetSimpleMultiChannelCodec.SIGNAL_START_MULTICHANNEL));
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/client/MixinConnectionScreen1.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.client;
26 |
27 | import com.ishland.raknetify.fabric.common.connection.RakNetClientConnectionUtil;
28 | import com.ishland.raknetify.common.util.PrefixUtil;
29 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
30 | import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
31 | import io.netty.channel.ChannelFuture;
32 | import net.minecraft.client.network.ServerAddress;
33 | import net.minecraft.network.ClientConnection;
34 | import org.spongepowered.asm.mixin.Dynamic;
35 | import org.spongepowered.asm.mixin.Final;
36 | import org.spongepowered.asm.mixin.Mixin;
37 | import org.spongepowered.asm.mixin.Mutable;
38 | import org.spongepowered.asm.mixin.Shadow;
39 | import org.spongepowered.asm.mixin.Unique;
40 | import org.spongepowered.asm.mixin.injection.At;
41 | import org.spongepowered.asm.mixin.injection.Inject;
42 | import org.spongepowered.asm.mixin.injection.Redirect;
43 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
44 |
45 | import java.net.InetSocketAddress;
46 |
47 | @Mixin(targets = "net/minecraft/client/gui/screen/multiplayer/ConnectScreen$1")
48 | public class MixinConnectionScreen1 extends Thread {
49 |
50 | @Mutable
51 | @Shadow
52 | @Final
53 | ServerAddress field_33737;
54 |
55 | @Unique
56 | private boolean isRaknet = false;
57 |
58 | @Unique
59 | private boolean raknetLargeMTU = false;
60 |
61 | @Inject(method = "*", at = @At("RETURN"), remap = false)
62 | private void onInit(CallbackInfo ci) {
63 | final PrefixUtil.Info info = PrefixUtil.getInfo(this.field_33737.getAddress());
64 | if (info.useRakNet()) {
65 | this.isRaknet = true;
66 | this.raknetLargeMTU = info.largeMTU();
67 | this.field_33737 = new ServerAddress(info.stripped(), this.field_33737.getPort());
68 | }
69 | }
70 |
71 | @Dynamic
72 | @WrapOperation(method = "run()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;method_10753(Ljava/net/InetSocketAddress;Z)Lnet/minecraft/network/ClientConnection;"), require = 0)
73 | private ClientConnection connectRaknet(InetSocketAddress address, boolean useEpoll, Operation original) {
74 | return this.isRaknet ? RakNetClientConnectionUtil.connect(address, useEpoll, this.raknetLargeMTU, original, false) : original.call(address, useEpoll);
75 | }
76 |
77 | @WrapOperation(method = "run()V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/network/ClientConnection;)Lio/netty/channel/ChannelFuture;"), require = 0)
78 | private ChannelFuture connectRaknet(InetSocketAddress address, boolean useEpoll, ClientConnection connection, Operation original) {
79 | return this.isRaknet ? RakNetClientConnectionUtil.connect(address, useEpoll, this.raknetLargeMTU, connection) : original.call(address, useEpoll, connection);
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/client/MixinMultiplayerServerListPinger.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.client;
26 |
27 | import com.ishland.raknetify.fabric.common.connection.RakNetClientConnectionUtil;
28 | import com.ishland.raknetify.common.util.PrefixUtil;
29 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
30 | import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
31 | import net.minecraft.client.network.MultiplayerServerListPinger;
32 | import net.minecraft.client.network.ServerAddress;
33 | import net.minecraft.client.network.ServerInfo;
34 | import net.minecraft.network.ClientConnection;
35 | import org.spongepowered.asm.mixin.Dynamic;
36 | import org.spongepowered.asm.mixin.Mixin;
37 | import org.spongepowered.asm.mixin.injection.At;
38 | import org.spongepowered.asm.mixin.injection.Redirect;
39 |
40 | import java.net.InetSocketAddress;
41 |
42 | @Mixin(MultiplayerServerListPinger.class)
43 | public abstract class MixinMultiplayerServerListPinger {
44 |
45 | @Dynamic
46 | @WrapOperation(method = {"add", "method_3003"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ServerAddress;parse(Ljava/lang/String;)Lnet/minecraft/client/network/ServerAddress;"))
47 | private ServerAddress modifyRaknetAddress(String address, Operation original) {
48 | final PrefixUtil.Info info = PrefixUtil.getInfo(address);
49 | return original.call(info.stripped());
50 | }
51 |
52 | @Dynamic
53 | @WrapOperation(method = {"add", "method_3003"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;method_10753(Ljava/net/InetSocketAddress;Z)Lnet/minecraft/network/ClientConnection;"), require = 0)
54 | private ClientConnection redirectConnect(InetSocketAddress address, boolean useEpoll, Operation original, ServerInfo entry, Runnable runnable) {
55 | final PrefixUtil.Info info = PrefixUtil.getInfo(entry.address);
56 | return info.useRakNet() ? RakNetClientConnectionUtil.connect(address, useEpoll, info.largeMTU(), original, false) : original.call(address, useEpoll);
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/client/MixinMultiplayerServerListPinger1.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.client;
26 |
27 | import com.ishland.raknetify.fabric.mixin.access.IClientConnection;
28 | import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
29 | import io.netty.channel.Channel;
30 | import net.minecraft.client.network.MultiplayerServerListPinger;
31 | import net.minecraft.client.network.ServerAddress;
32 | import net.minecraft.client.network.ServerInfo;
33 | import net.minecraft.network.ClientConnection;
34 | import net.minecraft.network.listener.ClientQueryPacketListener;
35 | import network.ycc.raknet.RakNet;
36 | import org.spongepowered.asm.mixin.Dynamic;
37 | import org.spongepowered.asm.mixin.Final;
38 | import org.spongepowered.asm.mixin.Mixin;
39 | import org.spongepowered.asm.mixin.Shadow;
40 | import org.spongepowered.asm.mixin.injection.At;
41 | import org.spongepowered.asm.mixin.injection.Inject;
42 | import org.spongepowered.asm.mixin.injection.Redirect;
43 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
44 |
45 | import java.net.InetSocketAddress;
46 |
47 | @Mixin(targets = "net/minecraft/client/network/MultiplayerServerListPinger$1")
48 | public abstract class MixinMultiplayerServerListPinger1 implements ClientQueryPacketListener {
49 |
50 | @Shadow
51 | @Final
52 | ClientConnection field_3774; // synthetic
53 |
54 | @Shadow
55 | @Final
56 | ServerInfo field_3776; // synthetic
57 |
58 | @Inject(method = "onResponse(Lnet/minecraft/network/packet/s2c/query/QueryResponseS2CPacket;)V", at = @At("RETURN"))
59 | private void setPingImmediately(CallbackInfo ci) {
60 | final Channel channel = ((IClientConnection) field_3774).getChannel();
61 | if (channel.config() instanceof RakNet.Config config) {
62 | field_3776.ping = config.getRTTNanos() / 1_000_000;
63 | }
64 | }
65 |
66 | @Dynamic
67 | @WrapWithCondition(method = {"method_10839(Lnet/minecraft/class_2561;)V", "onDisconnected"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/MultiplayerServerListPinger;ping(Ljava/net/InetSocketAddress;Lnet/minecraft/client/network/ServerAddress;Lnet/minecraft/client/network/ServerInfo;)V"), require = 0)
68 | private boolean noPingRaknet(MultiplayerServerListPinger instance, InetSocketAddress socketAddress, ServerAddress address, ServerInfo serverInfo) {
69 | final Channel channel = ((IClientConnection) field_3774).getChannel();
70 | return !(channel.config() instanceof RakNet.Config);
71 | }
72 |
73 | @Dynamic
74 | @WrapWithCondition(method = "method_10839(Lnet/minecraft/class_2561;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/MultiplayerServerListPinger;method_3001(Ljava/net/InetSocketAddress;Lnet/minecraft/client/network/ServerInfo;)V"), require = 0)
75 | private boolean noPingRaknet(MultiplayerServerListPinger instance, InetSocketAddress address, ServerInfo info) {
76 | final Channel channel = ((IClientConnection) field_3774).getChannel();
77 | return !(channel.config() instanceof RakNet.Config);
78 | }
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/client/MixinMultiplayerServerListPinger1_20_2.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.client;
26 |
27 | import com.ishland.raknetify.common.util.PrefixUtil;
28 | import com.ishland.raknetify.fabric.common.connection.RakNetClientConnectionUtil;
29 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
30 | import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
31 | import net.minecraft.client.network.MultiplayerServerListPinger;
32 | import net.minecraft.client.network.ServerInfo;
33 | import net.minecraft.network.ClientConnection;
34 | import net.minecraft.util.profiler.log.DebugSampleLog;
35 | import org.spongepowered.asm.mixin.Dynamic;
36 | import org.spongepowered.asm.mixin.Mixin;
37 | import org.spongepowered.asm.mixin.injection.At;
38 |
39 | import java.net.InetSocketAddress;
40 |
41 | @Mixin(MultiplayerServerListPinger.class)
42 | public class MixinMultiplayerServerListPinger1_20_2 {
43 |
44 | @Dynamic
45 | @WrapOperation(method = {"add", "method_3003"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;method_10753(Ljava/net/InetSocketAddress;ZLnet/minecraft/class_8743;)Lnet/minecraft/network/ClientConnection;"))
46 | private ClientConnection redirectConnect(InetSocketAddress address, boolean useEpoll, DebugSampleLog log, Operation original, ServerInfo entry, Runnable runnable) {
47 | final PrefixUtil.Info info = PrefixUtil.getInfo(entry.address);
48 | return info.useRakNet() ? RakNetClientConnectionUtil.connect(address, useEpoll, info.largeMTU(), original, true) : original.call(address, useEpoll, null);
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/client/MixinMultiplayerServerListPinger1_20_5.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.client;
26 |
27 | import com.ishland.raknetify.common.util.PrefixUtil;
28 | import com.ishland.raknetify.fabric.common.connection.RakNetClientConnectionUtil;
29 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
30 | import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
31 | import net.minecraft.client.network.MultiplayerServerListPinger;
32 | import net.minecraft.client.network.ServerInfo;
33 | import net.minecraft.network.ClientConnection;
34 | import net.minecraft.util.profiler.MultiValueDebugSampleLogImpl;
35 | import net.minecraft.util.profiler.log.DebugSampleLog;
36 | import net.minecraft.util.profiler.log.MultiValueDebugSampleLog;
37 | import org.spongepowered.asm.mixin.Dynamic;
38 | import org.spongepowered.asm.mixin.Mixin;
39 | import org.spongepowered.asm.mixin.injection.At;
40 |
41 | import java.net.InetSocketAddress;
42 |
43 | @Mixin(MultiplayerServerListPinger.class)
44 | public class MixinMultiplayerServerListPinger1_20_5 {
45 |
46 | @WrapOperation(method = "add", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/ClientConnection;connect(Ljava/net/InetSocketAddress;ZLnet/minecraft/util/profiler/MultiValueDebugSampleLogImpl;)Lnet/minecraft/network/ClientConnection;"))
47 | private ClientConnection redirectConnect(InetSocketAddress address, boolean useEpoll, MultiValueDebugSampleLogImpl log, Operation original, ServerInfo entry, Runnable runnable) {
48 | final PrefixUtil.Info info = PrefixUtil.getInfo(entry.address);
49 | return info.useRakNet() ? RakNetClientConnectionUtil.connect(address, useEpoll, info.largeMTU(), original, true) : original.call(address, useEpoll, null);
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/common/MixinClientConnection1.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.common;
26 |
27 | import com.ishland.raknetify.fabric.common.connection.RakNetFabricConnectionUtil;
28 | import io.netty.channel.Channel;
29 | import io.netty.channel.ChannelInitializer;
30 | import org.spongepowered.asm.mixin.Mixin;
31 | import org.spongepowered.asm.mixin.injection.At;
32 | import org.spongepowered.asm.mixin.injection.Inject;
33 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
34 |
35 | @Mixin(targets = "net/minecraft/network/ClientConnection$1")
36 | public abstract class MixinClientConnection1 extends ChannelInitializer {
37 |
38 | @Inject(method = "initChannel(Lio/netty/channel/Channel;)V", at = @At("HEAD"))
39 | private void onChannelInit(Channel channel, CallbackInfo ci) {
40 | RakNetFabricConnectionUtil.initChannel(channel);
41 | }
42 |
43 | @Inject(method = "initChannel(Lio/netty/channel/Channel;)V", at = @At("RETURN"))
44 | private void postChannelInit(Channel channel, CallbackInfo ci) {
45 | RakNetFabricConnectionUtil.postInitChannel(channel, true);
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/common/MixinClientConnection1_20_2.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.common;
26 |
27 | import com.ishland.raknetify.common.connection.SimpleMetricsLogger;
28 | import io.netty.channel.Channel;
29 | import net.minecraft.network.ClientConnection;
30 | import net.minecraft.network.handler.PacketSizeLogger;
31 | import network.ycc.raknet.RakNet;
32 | import org.jetbrains.annotations.Nullable;
33 | import org.spongepowered.asm.mixin.Mixin;
34 | import org.spongepowered.asm.mixin.Shadow;
35 | import org.spongepowered.asm.mixin.Unique;
36 | import org.spongepowered.asm.mixin.injection.At;
37 | import org.spongepowered.asm.mixin.injection.Inject;
38 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
39 |
40 | @Mixin(ClientConnection.class)
41 | public class MixinClientConnection1_20_2 {
42 |
43 | @Shadow private Channel channel;
44 | @Shadow private @Nullable PacketSizeLogger packetSizeLogger;
45 |
46 | @Unique
47 | private long raknetify$lastBytesIn = 0L;
48 |
49 | @Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/handler/PacketSizeLogger;push()V"))
50 | private void onPacketLoggerPush(CallbackInfo ci) {
51 | PacketSizeLogger logger = this.packetSizeLogger;
52 | if (logger != null && this.channel.config() instanceof RakNet.Config config && config.getMetrics() instanceof SimpleMetricsLogger simpleMetricsLogger) {
53 | long bytesIn = simpleMetricsLogger.getBytesIn();
54 | logger.increment((int) (bytesIn - this.raknetify$lastBytesIn));
55 | this.raknetify$lastBytesIn = bytesIn;
56 | }
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/common/MixinServerAddress.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.common;
26 |
27 | import com.ishland.raknetify.common.Constants;
28 | import com.ishland.raknetify.common.util.PrefixUtil;
29 | import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
30 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
31 | import net.minecraft.client.network.ServerAddress;
32 | import org.spongepowered.asm.mixin.Mixin;
33 |
34 | @Mixin(ServerAddress.class)
35 | public class MixinServerAddress {
36 |
37 | @WrapMethod(method = "parse")
38 | private static ServerAddress wrapParsing(String address, Operation original) {
39 | PrefixUtil.Info info = PrefixUtil.getInfo(address);
40 | if (info.useRakNet()) {
41 | ServerAddress addr = original.call(info.stripped());
42 | return new ServerAddress(
43 | (info.largeMTU() ? Constants.RAKNET_LARGE_MTU_PREFIX : Constants.RAKNET_PREFIX) + addr.getAddress(),
44 | addr.getPort()
45 | );
46 | } else {
47 | return original.call(address);
48 | }
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/common/encryption/MixinClientConnection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.common.encryption;
26 |
27 | import com.ishland.raknetify.common.connection.MultiChannelingStreamingCompression;
28 | import com.ishland.raknetify.common.connection.MultiChannellingEncryption;
29 | import io.netty.channel.Channel;
30 | import net.minecraft.network.ClientConnection;
31 | import net.minecraft.network.encryption.PacketDecryptor;
32 | import net.minecraft.network.encryption.PacketEncryptionManager;
33 | import net.minecraft.network.encryption.PacketEncryptor;
34 | import network.ycc.raknet.RakNet;
35 | import org.spongepowered.asm.mixin.Mixin;
36 | import org.spongepowered.asm.mixin.Overwrite;
37 | import org.spongepowered.asm.mixin.Shadow;
38 | import org.spongepowered.asm.mixin.injection.At;
39 | import org.spongepowered.asm.mixin.injection.Inject;
40 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
41 |
42 | import javax.crypto.Cipher;
43 |
44 | @Mixin(ClientConnection.class)
45 | public class MixinClientConnection {
46 |
47 | @Shadow
48 | private boolean encrypted;
49 |
50 | @Shadow
51 | private Channel channel;
52 |
53 | @Inject(method = "setupEncryption", at = @At("HEAD"), cancellable = true)
54 | public void beforeSetupEncryption(Cipher decryptionCipher, Cipher encryptionCipher, CallbackInfo ci) {
55 | if (this.channel.config() instanceof RakNet.Config) {
56 | ci.cancel();
57 | this.encrypted = true;
58 | try {
59 | this.channel.pipeline().remove("decrypt");
60 | this.channel.pipeline().remove("encrypt");
61 | } catch (Throwable ignored) {
62 | }
63 | try {
64 | this.channel.pipeline().remove(MultiChannellingEncryption.NAME);
65 | } catch (Throwable ignored) {
66 | }
67 | this.channel.pipeline().addBefore(MultiChannelingStreamingCompression.NAME, MultiChannellingEncryption.NAME,
68 | new MultiChannellingEncryption(decryptionCipher, encryptionCipher));
69 | }
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/fabric/src/main/java/com/ishland/raknetify/fabric/mixin/common/encryption/MixinPacketDecryptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is a part of the Raknetify project, licensed under MIT.
3 | *
4 | * Copyright (c) 2022-2025 ishland
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 |
25 | package com.ishland.raknetify.fabric.mixin.common.encryption;
26 |
27 | import com.ishland.raknetify.fabric.common.connection.encryption.PacketEncryptionManagerInterface;
28 | import io.netty.buffer.ByteBuf;
29 | import io.netty.channel.ChannelHandlerContext;
30 | import net.minecraft.network.encryption.PacketDecryptor;
31 | import net.minecraft.network.encryption.PacketEncryptionManager;
32 | import org.spongepowered.asm.mixin.Final;
33 | import org.spongepowered.asm.mixin.Mixin;
34 | import org.spongepowered.asm.mixin.Shadow;
35 | import org.spongepowered.asm.mixin.injection.At;
36 | import org.spongepowered.asm.mixin.injection.Inject;
37 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
38 |
39 | import java.util.List;
40 |
41 | @Mixin(PacketDecryptor.class)
42 | public class MixinPacketDecryptor {
43 |
44 | @Shadow @Final private PacketEncryptionManager manager;
45 |
46 | @Inject(method = "decode(Lio/netty/channel/ChannelHandlerContext;Lio/netty/buffer/ByteBuf;Ljava/util/List;)V", at = @At("HEAD"))
47 | private void preDecrypt(ChannelHandlerContext ctx, ByteBuf byteBuf, List