Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
2f48b07
Bumped version to 0.3.2-SNAPSHOT/0.4.3-SNAPSHOT
XIII-MC Jun 25, 2026
d38486b
Bump the dev-deps group with 2 updates
dependabot[bot] Jun 26, 2026
3b64af8
Merge pull request #25 from GTeamx/dependabot/gradle/dev/dev-deps-804…
XIII-MC Jun 27, 2026
494b690
Working on Bungeecord support
XIII-MC Jun 29, 2026
2ec7c8b
WIP: client settings/brand check
XIII-MC Jul 4, 2026
60416ed
Bump com.gradleup.shadow from 9.4.3 to 9.5.1 in the dev-deps group
dependabot[bot] Jul 6, 2026
f9f29b1
Made code a bit more readable
XIII-MC Jul 8, 2026
670d09f
Switched API to synchronous fetching instead of async
XIII-MC Jul 8, 2026
1d40461
Remade scanner
XIII-MC Jul 8, 2026
0882e81
Added platform type property
XIII-MC Jul 8, 2026
7ecdd4a
Added run parameters for scanner
XIII-MC Jul 8, 2026
00bc0a3
WIP: validation for bungeecord support
XIII-MC Jul 8, 2026
23312fc
Merge pull request #26 from GTeamx/dependabot/gradle/dev/dev-deps-c42…
XIII-MC Jul 8, 2026
793c537
Merge remote-tracking branch 'origin/dev' into dev
XIII-MC Jul 8, 2026
714b795
Fixed modern paper support to proper api version
XIII-MC Jul 8, 2026
a2c6b2b
Including project version to modern paper
XIII-MC Jul 8, 2026
4f254b2
Added version checking for spoofed disconnect message
XIII-MC Jul 8, 2026
1b56862
Updated modern paper support for 1.19.3 - 1.20.5
XIII-MC Jul 8, 2026
b2bba1f
Added kyori adventure api for DISCONNECT packet
XIII-MC Jul 8, 2026
9773db9
Remade the filter with better easier to understand logic
XIII-MC Jul 8, 2026
701971f
Merge spigot and paper module
rafi67000 Jul 8, 2026
7e79207
Remove unnecessary paper project
rafi67000 Jul 8, 2026
20d9b39
Add version catalog for easier dependency management and maintenance
rafi67000 Jul 8, 2026
d761cb1
Make use of kotlin DSL to simplify buildscript
rafi67000 Jul 8, 2026
3483bcc
Fixed properties not applying to platform.properties
XIII-MC Jul 9, 2026
0b21e56
Merge pull request #27 from rafi67000/feat/cleanup-buildscript
XIII-MC Jul 9, 2026
9b63105
Fixes issue #29
XIII-MC Jul 9, 2026
7f8cd1c
Removed no longer used config related commands.
XIII-MC Jul 9, 2026
79e059a
Fix shadow warnings by setting duplicates strategy
rafi67000 Jul 9, 2026
4b1a8eb
Merge pull request #31 from rafi67000/fix/shadow-warnings
XIII-MC Jul 9, 2026
6ba83d3
changed pe and lamp order
XIII-MC Jul 12, 2026
9b1bb30
Merge remote-tracking branch 'origin/dev' into dev
XIII-MC Jul 12, 2026
35ae562
extra space tickling my brain
XIII-MC Jul 12, 2026
cb2b8c3
Merge pull request #33 from GTeamX/prod
XIII-MC Jul 12, 2026
6dba8f6
Made more professional and cleaner
XIII-MC Jul 12, 2026
27277e9
Merge remote-tracking branch 'origin/dev' into dev
XIII-MC Jul 12, 2026
0c5882a
Removed unused client brand config settings
XIII-MC Jul 12, 2026
a319434
Optimized imports
XIII-MC Jul 12, 2026
4db252e
Added privacy section to comply with Modrinth
XIII-MC Jul 12, 2026
ad8e71c
Undid optimized import
XIII-MC Jul 12, 2026
cc21c8f
Fixed colors for velocity
XIII-MC Jul 12, 2026
397f9b1
Dynamically changing platform name if on paper
XIII-MC Jul 12, 2026
97adbdf
undo
XIII-MC Jul 12, 2026
4ebcb18
Added fool proof color
XIII-MC Jul 12, 2026
c52cc00
Fixed thread blocking update check
XIII-MC Jul 12, 2026
14c1c15
Updated scanner legit motd scan
XIII-MC Jul 12, 2026
0c9516a
Made API async again
XIII-MC Jul 12, 2026
3b2359b
Updated forged version
XIII-MC Jul 12, 2026
ce2c677
Properly fetching IP
XIII-MC Jul 12, 2026
9f3bbc3
Implemented API check
XIII-MC Jul 12, 2026
7e17886
Merge pull request #35 from GTeamX/prod
XIII-MC Jul 12, 2026
76e4044
Fix-ish (not proud) of async API fetching for proxies (issue #34)
XIII-MC Jul 12, 2026
f12e174
Made protocol version match new forged version
XIII-MC Jul 12, 2026
aa7d3a5
WIP: pipeline injection
rafi67000 Jul 8, 2026
1c336fe
ugly temporary trick so it works
rafi67000 Jul 8, 2026
71c1411
Use kotlin DSL instead of explicit set
rafi67000 Jul 12, 2026
320bebf
Properly handle netty
rafi67000 Jul 12, 2026
42de59f
Add velocity implementation of pipeline injection
rafi67000 Jul 12, 2026
de28b98
Refactor spigot implementation of pipeline injection
rafi67000 Jul 12, 2026
896d12d
Include packetevents license header in borrowed code
rafi67000 Jul 12, 2026
f666241
Fix a typo
rafi67000 Jul 12, 2026
188f333
Inject first before registering PacketEvents listener
rafi67000 Jul 12, 2026
4503aa8
Add bungeecord implementation of pipeline injection
rafi67000 Jul 12, 2026
d683508
Correct grammar
rafi67000 Jul 12, 2026
fa1c17c
Made fields final, cleanup code, made more readable
XIII-MC Jul 13, 2026
d4f692e
Removed platform-type to use PE's built in isProxy boolean
XIII-MC Jul 13, 2026
bd1aaec
Did a cleaner fix for API, now running on LOGIN_SUCCESS for proxies o…
XIII-MC Jul 13, 2026
c03d677
Fixed using the right wrapper (issue #34)
XIII-MC Jul 13, 2026
5897bc4
Clarify packet inspection description in README
XIII-MC Jul 14, 2026
8b183fb
Decode only legacy ping packet
rafi67000 Jul 15, 2026
438f679
Fixed cache check bad boolean
XIII-MC Jul 16, 2026
d204939
Added "this." to the timestamp var for uniformity across the project
XIII-MC Jul 16, 2026
9001df7
bump com.gradleup.shadow from 9.5.1 to 9.6.0 in the dev-deps group
dependabot[bot] Jul 16, 2026
5529a60
Merge pull request #38 from GTeamX/dependabot/gradle/dev/dev-deps-1b1…
XIII-MC Jul 17, 2026
dd9b759
Potential fix for #37, spoofing version when running on a proxy
XIII-MC Jul 16, 2026
d1bf4be
Remade the processDisconnect to support Bungee
Vagdedes2 Jul 17, 2026
edb35d5
Fixes #37, now works on BungeeCord
XIII-MC Jul 17, 2026
70f9d9b
Merge pull request #39 from GTeamX/proxy-version-spoof
XIII-MC Jul 18, 2026
1df5b4b
Merge branch 'dev' into wip/pipeline-injection
XIII-MC Jul 22, 2026
fd3071b
Fixed bungee netty injection
XIII-MC Jul 22, 2026
40858ac
Added support for older versions
XIII-MC Jul 22, 2026
ab7ac6c
Fixed velocity netty injection
XIII-MC Jul 22, 2026
c7fb1bc
Spoofing version for older versions kick message
XIII-MC Jul 22, 2026
7322f41
Simplified code
XIII-MC Jul 22, 2026
51c126c
Added channel for older disconnect on bungee
XIII-MC Jul 22, 2026
93201ae
Added handling for older legacy pings
XIII-MC Jul 22, 2026
a171464
Added netty responders to send forged legacy ping response
XIII-MC Jul 22, 2026
ae6dda0
Added netty responders to send forged legacy ping response
XIII-MC Jul 22, 2026
8d62260
Made latest version match config version
XIII-MC Jul 22, 2026
abc9cad
Better exception logging logic
XIII-MC Jul 22, 2026
a1fdfa2
Use predefined ChannelFutureListener#CLOSE
rafi67000 Jul 22, 2026
56ba887
Bump com.gradleup.shadow from 9.6.0 to 9.6.1 in the dev-deps group
dependabot[bot] Jul 22, 2026
168980b
Merge pull request #40 from GTeamX/dependabot/gradle/dev/dev-deps-a8c…
XIII-MC Jul 23, 2026
dcf9b81
Merge branch 'dev' into wip/pipeline-injection
XIII-MC Jul 23, 2026
8d6c5e8
Merge pull request #36 from rafi67000/wip/pipeline-injection
XIII-MC Jul 26, 2026
1a645b4
Validated Velocity support
XIII-MC Jul 30, 2026
a7c70a0
Bumped version
XIII-MC Jul 30, 2026
7b66c3e
Merge branch 'prod' into dev
XIII-MC Jul 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .run/Scanner.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
<option name="MAIN_CLASS_NAME" value="Main" />
<module name="scanner" />
<option name="PROGRAM_PARAMETERS" value="127.0.0.1 25565" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/scanner" />
<method v="2">
<option name="Make" enabled="true" />
Expand Down
391 changes: 94 additions & 297 deletions README.md

Large diffs are not rendered by default.

10 changes: 1 addition & 9 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
// Project related options.
extra["coreVersion"] = "0.4.2-rc"

// Dependency related options.
extra["lampVersion"] = "4.0.0-rc.17"
extra["packetEventsVersion"] = "2.13.0"
extra["bstatsVersion"] = "3.2.1"

subprojects {

group = "cloud.gteam"
version = "0.3.1-rc"
version = "0.4.0"

repositories {
mavenCentral()
Expand Down
65 changes: 31 additions & 34 deletions bungeecord/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
plugins {

`java-library`
id("com.gradleup.shadow") version "9.4.2"
alias(libs.plugins.shadow)

}

java {

toolchain {
languageVersion.set(JavaLanguageVersion.of(8))
languageVersion = JavaLanguageVersion.of(8)
}

sourceCompatibility = JavaVersion.VERSION_1_8
Expand All @@ -31,57 +31,50 @@ repositories {

dependencies {

// Get versions.
val lampVersion: String by rootProject.extra
val packetEventsVersion: String by rootProject.extra
val bstatsVersion: String by rootProject.extra

// Dependencies.
implementation("org.bstats:bstats-bungeecord:$bstatsVersion")
implementation("io.github.revxrsal:lamp.common:$lampVersion")
implementation("io.github.revxrsal:lamp.bungee:$lampVersion")
implementation(libs.bstats.bungeecord)
implementation(libs.lamp.common)
implementation(libs.lamp.bungee)

compileOnly("com.github.retrooper:packetevents-bungeecord:$packetEventsVersion")
compileOnly("net.md-5:bungeecord-api:1.16-R0.4")
compileOnly(libs.packetevents.bungeecord)
compileOnly(libs.bungeecord.api)

// Core implementation.
implementation(project(path = ":core", configuration = "shadow"))
compileOnly(project(":core"))

}

tasks.processResources {

// Get versions.
val packetEventsVersion: String by rootProject.extra
val coreVersion: String by rootProject.extra

// Replace bungee.yml
filesMatching("bungee.yml") {
expand("version" to project.version)
}
inputs.property("name", project.name)
inputs.property("version", project.version)
inputs.property("coreVersion", libs.versions.coreVersion.get())
inputs.property("packeteventsVersion", libs.versions.packetevents.get())

// Replace properties.
filesMatching("platform.properties") {

expand(
"name" to project.name,
"version" to project.version,
"coreVersion" to coreVersion,
"packeteventsVersion" to packetEventsVersion
)

filesMatching(listOf("bungee.yml", "platform.properties")) {
expand(inputs.properties)
}
}

// A trick so netty used by async-http-client is always
// relocated, but netty used by injector is always provided by platform (spigot, bungeecord, velocity)
val coreProvider = provider { project(":core").tasks.shadowJar.flatMap { it.archiveFile } }

tasks.jar {
enabled = false // only shadowJar is used
}

tasks.shadowJar {

// Wait for the core shadowJar to finish.
dependsOn(project(":core").tasks.named("shadowJar"))
dependsOn(":core:shadowJar")

archiveBaseName = "CoralGate-Bungeecord"
archiveVersion = project.version.toString()
archiveClassifier = ""

archiveBaseName.set("CoralGate-Bungeecord")
archiveVersion.set(project.version.toString())
archiveClassifier.set("")
from(zipTree(coreProvider)) // include shadowed core

// Relocate bStats.
relocate("org.bstats", "cloud.gteam.coralgate.libs.bstats")
Expand All @@ -90,6 +83,10 @@ tasks.shadowJar {
exclude("META-INF/*.DSA")
exclude("META-INF/*.RSA")

filesMatching("META-INF/*.kotlin_module") {
duplicatesStrategy = DuplicatesStrategy.INCLUDE
}

}

tasks.build {
Expand Down
12 changes: 9 additions & 3 deletions bungeecord/src/main/java/cloud/gteam/coralgate/BungeePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import cloud.gteam.coralgate.commands.BungeePermissionChecker;
import cloud.gteam.coralgate.commands.CoralGateCommand;
import cloud.gteam.coralgate.commands.permissions.PermissionFactory;
import cloud.gteam.coralgate.injector.BungeeInjector;
import cloud.gteam.coralgate.injector.handlers.BungeeNettyResponder;
import cloud.gteam.coralgate.processor.NetworkProcessor;
import cloud.gteam.coralgate.utils.PlatformUtils;
import com.github.retrooper.packetevents.PacketEvents;
Expand All @@ -34,11 +36,15 @@
public final class BungeePlugin extends Plugin {

private final CorePlugin corePlugin = new CorePlugin();
private final BungeeInjector injector = new BungeeInjector();

@Override
public void onLoad() {
PacketEvents.getAPI().getEventManager().registerListener(
new NetworkProcessor(getCorePlugin()), PacketListenerPriority.HIGHEST);

this.injector.inject();

PacketEvents.getAPI().getEventManager().registerListener(new NetworkProcessor(getCorePlugin()), PacketListenerPriority.HIGHEST);

}

@Override
Expand All @@ -48,7 +54,7 @@ public void onEnable() {
new Metrics(this, 29439);

// Load core.
this.corePlugin.onEnable(this.getLogger(), getDataFolder(), this.getProxy().getConfig().isOnlineMode(), "config.yml", PlatformUtils.loadProperties(this.getClass()));
this.corePlugin.onEnable(this.getLogger(), getDataFolder(), this.getProxy().getConfig().isOnlineMode(), "config.yml", PlatformUtils.loadProperties(this.getClass()), new BungeeNettyResponder());

// Load commands.
final Lamp<BungeeCommandActor> bukkitCommandActor = BungeeLamp.builder(this)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package cloud.gteam.coralgate.injector;

import cloud.gteam.coralgate.injector.connection.BungeeChannelInitializer;
import com.github.retrooper.packetevents.util.reflection.Reflection;
import io.github.retrooper.packetevents.injector.SetWrapper;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import net.md_5.bungee.api.ProxyServer;

import java.lang.reflect.Field;
import java.util.Set;

public class BungeeInjector {

public static final String DECODER_NAME = "cg-decoder";
private static final Field LISTENERS_FIELD;

static {

LISTENERS_FIELD = Reflection.getField(ProxyServer.getInstance().getClass(), "listeners");
LISTENERS_FIELD.setAccessible(true);

}

public void injectChannel(final Channel channel) {

Field initializerField = null;
ChannelHandler bootstrapAcceptor = null;
for (String channelName : channel.pipeline().names()) {

if (channelName.contains("QueryHandler")) {
return; // query handler, abort injection.
}

final ChannelHandler handler = channel.pipeline().get(channelName);
if (handler == null) {
continue;
}

try {

final Field f = handler.getClass().getDeclaredField("childHandler");
f.setAccessible(true);
bootstrapAcceptor = handler;
initializerField = f;

} catch (final Exception ignored) {}

}

if (bootstrapAcceptor == null) {

bootstrapAcceptor = channel.pipeline().first();
try {

initializerField = bootstrapAcceptor.getClass().getDeclaredField("childHandler");
initializerField.setAccessible(true);

} catch (final NoSuchFieldException e) {
throw new RuntimeException(e);
}

}

final ChannelInitializer<Channel> newInitializer;
try {
newInitializer = new BungeeChannelInitializer(initializerField.get(bootstrapAcceptor));
} catch (final IllegalAccessException e) {
throw new RuntimeException(e);
}

try {
initializerField.set(bootstrapAcceptor, newInitializer);
} catch (final IllegalAccessException e) {
throw new RuntimeException(e);
}

}

public void inject() {

try {

final Set<Channel> listeners = (Set<Channel>) LISTENERS_FIELD.get(ProxyServer.getInstance());

for (final Channel channel : listeners) {
injectChannel(channel);
}

final Set<Channel> wrapper = new SetWrapper<>(listeners, this::injectChannel);
LISTENERS_FIELD.set(ProxyServer.getInstance(), wrapper);

} catch (final IllegalAccessException e) {
throw new RuntimeException("Failed to inject custom listeners into ProxyServer instance. See error: ", e);
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* This file is part of packetevents - https://github.com/retrooper/packetevents
* Copyright (C) 2022 retrooper and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package cloud.gteam.coralgate.injector.connection;

import com.github.retrooper.packetevents.protocol.ConnectionState;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Method;

public class BungeeChannelInitializer extends ChannelInitializer<Channel> {

private static final Method INIT_CHANNEL_METHOD;

static {

try {

INIT_CHANNEL_METHOD = ChannelInitializer.class.getDeclaredMethod("initChannel", Channel.class);
INIT_CHANNEL_METHOD.setAccessible(true);

} catch (final NoSuchMethodException e) {
throw new RuntimeException(e);
}

}

private final Object oldInitializer;

public BungeeChannelInitializer(final Object oldInitializer) {
this.oldInitializer = oldInitializer;
}

@Override
protected void initChannel(final @NotNull Channel channel) throws Exception {

if (!channel.isActive()) {
return;
}

INIT_CHANNEL_METHOD.invoke(this.oldInitializer, channel);

// No injection if "legacy-decoder" is not present.
if (channel.pipeline().get("legacy-decoder") == null) {
return;
}

ServerConnectionInitializer.initChannel(channel, ConnectionState.HANDSHAKING);

}

}
Loading
Loading