Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
00c8846
Made some variables final and fixed a ridiculous networking bug in an…
p0t4t0sandwich Jan 26, 2026
e097f00
Merge pull request #1 from p0t4t0sandwich/fix/payload-bugs
p0t4t0sandwich Jan 26, 2026
36b780f
Added a PostProcessor to ModernForwarding to make supporting hybrids …
p0t4t0sandwich Jan 26, 2026
e78eea2
Added more version-specific Arclight post-processors
p0t4t0sandwich Jan 26, 2026
5dd657e
Renamed the interfaces to make more sense at a glance
p0t4t0sandwich Jan 26, 2026
5576146
Fixed some version bounds
p0t4t0sandwich Jan 27, 2026
b83c3b8
Fixed wording
p0t4t0sandwich Jan 27, 2026
d646103
Added Mohist PostProcessors
p0t4t0sandwich Jan 27, 2026
429960b
Added PostProcessors for most major hybrids and versions
p0t4t0sandwich Jan 27, 2026
5b131a2
Merge pull request #2 from p0t4t0sandwich/improvement/hybrid-compatib…
p0t4t0sandwich Jan 27, 2026
60cc437
PostProcessors are now held in a SequencedCollection for added flexib…
p0t4t0sandwich Jan 27, 2026
3888664
Added compat for SpongeAPI 8 and 9, hopefully resolving the long-stan…
p0t4t0sandwich Jan 27, 2026
1b4ae84
Added boolean return value for PostProcessors to accommodate for Spon…
p0t4t0sandwich Jan 27, 2026
70f2289
Changed PostProcessors to use an ArrayList
p0t4t0sandwich Jan 30, 2026
1c845fd
Finally fixed SpongeForge 1.16.5 PreLogin bug
p0t4t0sandwich Jan 30, 2026
c79aa74
Fixed Arclight PreLogin compat
p0t4t0sandwich Jan 30, 2026
2fc6e64
Added Arclight-specific HandleHello mixins due to their overwrites
p0t4t0sandwich Jan 30, 2026
b7a65ca
Made CrossStich info dump debug line print to debug instead of info
p0t4t0sandwich Jan 30, 2026
2075b5a
Renamed and cleaned up PreLogin compat classes
p0t4t0sandwich Jan 30, 2026
8a3aee6
Renamed and compat packages to compatibility
p0t4t0sandwich Jan 30, 2026
7910988
Fixed some method handle stuff, since the inner class is non-static
p0t4t0sandwich Jan 31, 2026
1909aa9
Mohist seem to change handleHello somehow, so they're getting the sam…
p0t4t0sandwich Jan 31, 2026
6ee03d6
Moved dev notes
p0t4t0sandwich Jan 31, 2026
0e1f021
Added more hybrids to the startup logic
p0t4t0sandwich Jan 31, 2026
ac76aa3
Updated compatibility docs
p0t4t0sandwich Jan 31, 2026
b676c58
Added some debug logging during post-processor registration
p0t4t0sandwich Jan 31, 2026
5eacc5f
Renamed PreLogin compatibility doc, since it includes Sponge
p0t4t0sandwich Jan 31, 2026
508ae6e
Modified login PostProcessors to take Cancellable as an input as oppo…
p0t4t0sandwich Feb 4, 2026
aa32c25
Added a min version constraint to a 1.20.2+ field, the mixin should b…
p0t4t0sandwich Feb 7, 2026
b71c1d6
Created new prelogin package
p0t4t0sandwich Feb 8, 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
111 changes: 110 additions & 1 deletion common/src/main/java/org/adde0109/pcf/PCF.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import dev.neuralnexus.taterapi.loader.EntrypointLoader;
import dev.neuralnexus.taterapi.logger.Logger;
import dev.neuralnexus.taterapi.meta.Constraint;
import dev.neuralnexus.taterapi.meta.Constraints;
import dev.neuralnexus.taterapi.meta.MetaAPI;
import dev.neuralnexus.taterapi.meta.MinecraftVersion;
import dev.neuralnexus.taterapi.meta.MinecraftVersions;
Expand All @@ -14,6 +15,11 @@
import dev.neuralnexus.taterapi.registries.AdapterRegistry;

import org.adde0109.pcf.forwarding.Mode;
import org.adde0109.pcf.forwarding.compatibility.prelogin.ArclightPreLogin;
import org.adde0109.pcf.forwarding.compatibility.prelogin.MohistPreLogin;
import org.adde0109.pcf.forwarding.compatibility.prelogin.SpigotPreLogin;
import org.adde0109.pcf.forwarding.compatibility.prelogin.SpongePreLogin;
import org.adde0109.pcf.forwarding.modern.ModernForwarding;
import org.adde0109.pcf.forwarding.modern.PlayerInfoQueryPayload;
import org.adde0109.pcf.forwarding.modern.VelocityProxy;
import org.jetbrains.annotations.ApiStatus;
Expand Down Expand Up @@ -48,7 +54,7 @@ void onInit() {
Platform platform = api.platform();

// spotless:off
PCF.logger.info("Initializing Proxy Compatible Forge on "
PCF.logger.info("Initializing " + MOD_NAME + " on "
+ "Minecraft " + mcv
+ " (" + platform + " " + api.meta().apiVersion() + ")");
// spotless:on
Expand All @@ -74,9 +80,112 @@ void onInit() {
}
loader.onInit();

// Modern forwarding init
if (this.forwarding().enabled() && this.forwarding().mode().equals(Mode.MODERN)) {
NetworkRegistry.registerQueryPayload(
PlayerInfoQueryPayload.IDENTIFIER, PlayerInfoQueryPayload.STREAM_CODEC);

if (Constraint.builder().platform(Platforms.ARCLIGHT).result()) {
logger.debug("Arclight detected, applying pre-login post processor");
if (Constraint.range(MinecraftVersions.V14, MinecraftVersions.V20_1).result()) {
ModernForwarding.postProcessors.removeFirst();
ModernForwarding.postProcessors.add(
(slpl, profile, c) -> {
slpl.bridge$setGameProfile(profile);
ArclightPreLogin.V14.preLogin(slpl);
});
} else if (Constraint.builder().version(MinecraftVersions.V20_2).result()) {
ModernForwarding.postProcessors.removeFirst();
ModernForwarding.postProcessors.add(
(slpl, profile, c) -> ArclightPreLogin.V20_2.preLogin(slpl, profile));
} else if (Constraint.noLessThan(MinecraftVersions.V20_3).result()) {
ModernForwarding.postProcessors.removeFirst();
ModernForwarding.postProcessors.add(
(slpl, profile, c) ->
((ArclightPreLogin.V20_4) slpl).bridge$preLogin(profile));
}
} else if (Constraint.builder()
.platform(Platforms.MOHIST)
.version(MinecraftVersions.V20_1)
.result()) {
logger.debug("Mohist detected, applying pre-login post processor");
ModernForwarding.postProcessors.removeFirst();
ModernForwarding.postProcessors.add(
(slpl, profile, c) -> {
slpl.bridge$setGameProfile(profile);
MohistPreLogin.V20_1.fireEvents(slpl);
});
} else if (Constraint.builder()
.platform(Platforms.YOUER)
.version(MinecraftVersions.V21_1)
.result()) {
logger.debug("Youer detected, applying pre-login post processor");
ModernForwarding.postProcessors.removeFirst();
ModernForwarding.postProcessors.add(
(slpl, profile, c) -> {
MohistPreLogin.Youer.fireEvents(slpl, profile);
slpl.bridge$startClientVerification(profile);
});
} else if (Constraints.builder()
.or(
Constraint.range(MinecraftVersions.V12_2, MinecraftVersions.V19_4)
.platform(
Platforms.CATSERVER, Platforms.MAGMA, Platforms.MOHIST),
Constraint.builder()
.platform(Platforms.MAGMA, Platforms.KETTING)
.version(MinecraftVersions.V20_1))
.result()) {
logger.debug("Forge+Bukkit hybrid detected, applying pre-login post processor");
ModernForwarding.postProcessors.removeFirst();
ModernForwarding.postProcessors.add(
(slpl, profile, c) -> {
slpl.bridge$setGameProfile(profile);
SpigotPreLogin.Legacy.fireEvents(slpl);
});
} else if (Constraints.builder()
.or(
Constraint.range(MinecraftVersions.V20_2, MinecraftVersions.V20_4)
.platform(Platforms.KETTING),
Constraint.builder()
.platform(Platforms.MOHIST)
.version(MinecraftVersions.V20_2))
.result()) {
logger.debug(
"[Neo]Forge+Bukkit hybrid detected, applying pre-login post processor");
ModernForwarding.postProcessors.removeFirst();
ModernForwarding.postProcessors.add(
(slpl, profile, c) -> SpigotPreLogin.V20_2.fireEvents(slpl, profile));
} else if (Constraints.builder()
.or(
Constraint.builder()
.platform(Platforms.MAGMA)
.version(MinecraftVersions.V21_1),
Constraint.builder()
.platform(Platforms.MOHIST)
.version(MinecraftVersions.V21_1, MinecraftVersions.V21_4),
Constraint.range(MinecraftVersions.V21_11, MinecraftVersions.V26_1)
.platform(Platforms.YOUER),
Constraint.builder()
.platform(Platforms.NEOTENET)
.version(MinecraftVersions.V21_1, MinecraftVersions.V21_10))
.result()) {
logger.debug(
"[Neo]Forge+Bukkit hybrid detected, applying pre-login post processor");
ModernForwarding.postProcessors.addFirst(
(slpl, profile, c) ->
((SpigotPreLogin.V20_5) slpl).callPlayerPreLoginEvents(profile));
}

if (Constraint.range(MinecraftVersions.V16, MinecraftVersions.V18_2)
.platform(Platforms.SPONGE)
.result()) {
logger.debug("SpongeAPI 8 or 9 detected, applying pre-login post processor");
ModernForwarding.postProcessors.addFirst(
(slpl, profile, c) -> {
slpl.bridge$setGameProfile(profile);
c.setCancelled(SpongePreLogin.API8.fireAuthEvent(slpl));
});
}
}

Constraint.Evaluator.DEBUG = debug;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import io.netty.buffer.Unpooled;

import org.adde0109.pcf.PCF;
import org.adde0109.pcf.crossstitch.compat.ArgumentEdgeCases;
import org.adde0109.pcf.crossstitch.compatibility.ArgumentEdgeCases;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.adde0109.pcf.crossstitch.compat;
package org.adde0109.pcf.crossstitch.compatibility;

import dev.neuralnexus.taterapi.meta.Constraint;
import dev.neuralnexus.taterapi.meta.MinecraftVersions;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.adde0109.pcf.forwarding.compatibility.prelogin;

import com.mojang.authlib.GameProfile;

import org.adde0109.pcf.forwarding.modern.ServerLoginPacketListenerBridge;
import org.jspecify.annotations.NonNull;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

public interface ArclightPreLogin {
/**
* <a
* href="https://github.com/IzzelAliz/Arclight/blob/Trials/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerLoginNetHandlerMixin.java">Used
* for Arclight 1.14 - 1.20.1</a>
*/
class V14 {
private static MethodHandle preLogin;

public static void preLogin(final @NonNull ServerLoginPacketListenerBridge slpl)
throws Exception {
if (preLogin == null) {
final MethodHandles.Lookup lookup =
MethodHandles.privateLookupIn(slpl.getClass(), MethodHandles.lookup());
final MethodType methodType = MethodType.methodType(void.class);
preLogin = lookup.findVirtual(slpl.getClass(), "arclight$preLogin", methodType);
}

try {
preLogin.invoke(slpl);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
}

/**
* <a
* href="https://github.com/IzzelAliz/Arclight/blob/Net/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerLoginNetHandlerMixin.java">Used
* for Arclight 1.20.2 - 1.20.3</a>
*/
class V20_2 {
private static MethodHandle preLogin;

public static void preLogin(
final @NonNull ServerLoginPacketListenerBridge slpl,
final @NonNull GameProfile profile)
throws Exception {
if (preLogin == null) {
final MethodHandles.Lookup lookup =
MethodHandles.privateLookupIn(slpl.getClass(), MethodHandles.lookup());
final MethodType methodType = MethodType.methodType(void.class, GameProfile.class);
preLogin = lookup.findVirtual(slpl.getClass(), "arclight$preLogin", methodType);
}

try {
preLogin.invoke(slpl, profile);
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
}

/**
* <a
* href="https://github.com/IzzelAliz/Arclight/blob/Whisper/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerLoginNetHandlerMixin.java">Used
* for Arclight 1.20.4+.</a> <br>
* {@link SpigotPreLogin.V20_5#callPlayerPreLoginEvents(GameProfile)} could be used, but it is
* private in <a
* href="https://github.com/IzzelAliz/Arclight/blob/FeudalKings/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/network/ServerLoginPacketListenerImplMixin.java">Arclight
* 1.20.5+.</a>
*/
interface V20_4 {
void bridge$preLogin(GameProfile profile) throws Exception;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package org.adde0109.pcf.forwarding.compatibility.prelogin;

import com.mojang.authlib.GameProfile;

import org.adde0109.pcf.forwarding.modern.ServerLoginPacketListenerBridge;
import org.jspecify.annotations.NonNull;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;

public interface MohistPreLogin {
/**
* <a
* href="https://github.com/Teneted/Tenet/blob/1.20.1/patches/minecraft/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch">Used
* in Mohist 1.20.1</a>
*/
class V20_1 {
private static MethodHandle loginHandler;
private static MethodHandle fireEvents;

public static void fireEvents(final @NonNull ServerLoginPacketListenerBridge slpl)
throws Exception {
if (loginHandler == null || fireEvents == null) {
final MethodHandles.Lookup lookup = MethodHandles.lookup();

final Class<?> clazz = Class.forName("com.mohistmc.bukkit.LoginHandler");
final MethodType cType = MethodType.methodType(void.class);
loginHandler = lookup.findConstructor(clazz, cType);

final MethodType methodType = MethodType.methodType(void.class, slpl.getClass());
fireEvents = lookup.findVirtual(clazz, "fireEvents", methodType);
}

try {
fireEvents.invoke(loginHandler.invoke(), slpl);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}

/**
* <a
* href="https://github.com/MohistMC/Youer/blob/1.21.1/patches/net/minecraft/server/network/ServerLoginPacketListenerImpl.java.patch">Used
* in Youer 1.21.1</a>
*/
class Youer {
private static MethodHandle loginHandler;
private static MethodHandle fireEvents;

public static void fireEvents(
final @NonNull ServerLoginPacketListenerBridge slpl,
final @NonNull GameProfile profile)
throws Exception {
if (loginHandler == null || fireEvents == null) {
final MethodHandles.Lookup lookup = MethodHandles.lookup();

final Class<?> clazz = Class.forName("com.mohistmc.youer.bukkit.LoginHandler");
final MethodType cType = MethodType.methodType(void.class);
loginHandler = lookup.findConstructor(clazz, cType);

final MethodType methodType =
MethodType.methodType(void.class, slpl.getClass(), GameProfile.class);
fireEvents = lookup.findVirtual(clazz, "fireEvents", methodType);
}

try {
fireEvents.invoke(loginHandler.invoke(), slpl, profile);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
}
Loading