Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Floodgate-Fabric merge #466

Draft
wants to merge 30 commits into
base: development
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
63d1d38
Initial build script start on Fabric
Konicai Sep 6, 2022
db41cec
Try quilt-loom
Konicai Sep 6, 2022
5ecb120
Add minecraft/quilt dependencies
Konicai Sep 6, 2022
def9079
Fix jackson issue and repositories issue
Konicai Sep 6, 2022
cc48dac
setup more dependencies
Konicai Sep 6, 2022
5b9bd51
Add remapped shadow jar, update gradle
Konicai Sep 21, 2022
c758e9e
Doc and formatting
Konicai Sep 21, 2022
dd5e194
Fix shadow configurations
Konicai Sep 21, 2022
7840bf8
Update github actions
Konicai Sep 21, 2022
ff7b397
Use loom 1.0-SNAPSHOT
Konicai Sep 21, 2022
2b43ca9
Add loom to root project (no apply)
Konicai Sep 22, 2022
375e31e
Merge remote-tracking branch 'upstream/development' into pr/353
onebeastchris Jun 20, 2023
5e18b85
start on updating the floodgate-fabric merge pr to the latest floodga…
onebeastchris Jun 20, 2023
ec798c7
more changes
onebeastchris Jun 20, 2023
0b432fb
isolated might work now.. how logger work?
onebeastchris Jun 20, 2023
b99e050
loom works now, yay
onebeastchris Jun 20, 2023
f840c11
loom libs reference works now
onebeastchris Jun 21, 2023
15910ce
we kinda need mixins, oops
onebeastchris Jun 21, 2023
b93fcb3
Merge remote-tracking branch 'upstream/development' into pr/353
onebeastchris Jul 14, 2023
515bdf6
yeet FabricMod.java
onebeastchris Jul 14, 2023
4480f1d
loom wants its ~ own ~ repos
onebeastchris Jul 14, 2023
71f88dd
Merge remote-tracking branch 'upstream/development' into feature/fabric
onebeastchris Nov 10, 2023
0773637
Move to Gradle 8.4
onebeastchris Nov 11, 2023
fdbb5dc
finally got architectury set up
onebeastchris Nov 11, 2023
edaab84
Add initial mixins
onebeastchris Nov 17, 2023
5f7ebd0
fix aw, start working on fixing building... meh this is weird
onebeastchris Nov 17, 2023
5688102
Version bump
onebeastchris Nov 18, 2023
a0e46a3
apply base coventions plugin also to modded
onebeastchris Nov 19, 2023
a5b14dc
let's try strict versions?
onebeastchris Nov 19, 2023
89b19ab
let's temporarily uncomment h2 who literally insert a singular java 2…
onebeastchris Nov 19, 2023
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
Prev Previous commit
Next Next commit
Add initial mixins
Port fabric -> mod module
Re-add AW
  • Loading branch information
onebeastchris committed Nov 17, 2023
commit edaab84a7133bdcea24cd5e66edd222b6d000f47
5 changes: 4 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -4,4 +4,7 @@ org.gradle.parallel=true
systemProp.org.gradle.unsafe.kotlin.assignment=true

version=2.2.2-SNAPSHOT
micronautVersion=4.1.3
micronautVersion=4.1.3

# Increase ram for Gradle JVM
org.gradle.jvmargs=-Xmx4G
10 changes: 8 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -38,6 +38,9 @@ fabric_permissions_api = "0.2-SNAPSHOT"

# forge

# mod common
mixin = "0.8.5"

# architectury
architectury_plugin = "3.4-SNAPSHOT"
architectury_loom = "1.1-SNAPSHOT"
@@ -112,9 +115,13 @@ fabric-loader = { group = "net.fabricmc", name = "fabric-loader", version.ref =
fabric-api = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fabric_api" }
cloud-fabric = { module = "cloud.commandframework:cloud-fabric", version.ref = "cloud" }
kyori-adventure = { module = "net.kyori:adventure-platform-fabric", version.ref = "fabric_adventure" }
# loom = { group = "net.fabricmc", name = "fabric-loom", version.ref = "loom" }
fabric-permissions-api = { module = "me.lucko:fabric-permissions-api", version.ref = "fabric_permissions_api" }

# forge TODO

# mod common
mixin = { group = "org.spongepowered", name = "mixin", version.ref = "mixin" }

# buildSrc
checker-qual = { module = "org.checkerframework:checker-qual", version.ref = "checkerframework" }

@@ -127,7 +134,6 @@ gradle-idea-ext = { module = "gradle.plugin.org.jetbrains.gradle.plugin.idea-ext
[plugins]
micronaut = { id = "io.micronaut.library", version.ref = "micronaut-gradle" }
lombok = { id = "io.freefair.lombok", version.ref = "lombok" }
# loom = { id = "fabric-loom", version.ref = "loom" } # todo remove
architectury-plugin = { id = "architectury-plugin.gradle.plugin", version.ref = "architectury_plugin" }
architecury-loom = { id = "dev.architectury.loom.gradle.plugin", version.ref = "architectury_loom" }

17 changes: 16 additions & 1 deletion mod/common/base/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
architectury {
common("fabric")
}
}

loom {
accessWidenerPath.set(file("src/main/resources/floodgate.accesswidener"))
}

dependencies {
api(projects.core)

compileOnly(libs.mixin)
annotationProcessor(projects.core)
annotationProcessor(libs.micronaut.inject.java)
compileOnlyApi(projects.isolation)
}

provided(libs.gson)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.geysermc.floodgate.mod;

import io.micronaut.context.ApplicationContext;
import lombok.Getter;
import org.geysermc.floodgate.core.FloodgatePlatform;
import org.geysermc.floodgate.isolation.library.LibraryManager;

public abstract class ModPlatform extends FloodgatePlatform {

@Getter
protected ApplicationContext context;

protected ModPlatform(LibraryManager manager) {
super(manager);
}

@Override
public void enable() throws RuntimeException {
super.enable();
}

@Override
public boolean isProxy() {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package org.geysermc.floodgate.mod.addon.data;

import io.netty.channel.Channel;
import io.netty.util.AttributeKey;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.inject.Singleton;
import org.geysermc.api.connection.Connection;
import org.geysermc.floodgate.api.inject.InjectorAddon;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.core.config.FloodgateConfig;
import org.geysermc.floodgate.core.connection.DataSeeker;
import org.geysermc.floodgate.core.connection.FloodgateDataHandler;
import org.geysermc.floodgate.core.util.Utils;

@Singleton
public class ModDataAddon implements InjectorAddon {

@Inject
DataSeeker dataSeeker;

@Inject
FloodgateDataHandler handshakeHandler;

@Inject
FloodgateConfig config;

@Inject
FloodgateLogger logger;

@Inject
@Named("packetHandler")
String packetHandlerName;

@Inject
@Named("connectionAttribute")
AttributeKey<Connection> connectionAttribute;

@Inject
@Named("kickMessageAttribute")
AttributeKey<String> kickMessageAttribute;

@Override
public void onInject(Channel channel, boolean toServer) {
var dataHandler = new ModDataHandler(
dataSeeker, handshakeHandler, config, logger, connectionAttribute, kickMessageAttribute);
channel.pipeline().addBefore(packetHandlerName, "floodgate_data_handler", dataHandler);
}

@Override
public void onChannelClosed(Channel channel) {
InjectorAddon.super.onChannelClosed(channel);
}

@Override
public void onRemoveInject(Channel channel) {
Utils.removeHandler(channel.pipeline(), "floodgate_data_handler");
}

@Override
public boolean shouldInject() {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package org.geysermc.floodgate.mod.addon.data;

import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.AttributeKey;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import net.minecraft.DefaultUncaughtExceptionHandler;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.handshake.ClientIntentionPacket;
import net.minecraft.network.protocol.login.ServerboundHelloPacket;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerLoginPacketListenerImpl;
import org.geysermc.api.connection.Connection;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.core.addon.data.CommonNettyDataHandler;
import org.geysermc.floodgate.core.addon.data.PacketBlocker;
import org.geysermc.floodgate.core.config.FloodgateConfig;
import org.geysermc.floodgate.core.connection.DataSeeker;
import org.geysermc.floodgate.core.connection.FloodgateDataHandler;
import org.geysermc.floodgate.mod.mixin.ClientIntentionPacketMixinInterface;
import org.geysermc.floodgate.mod.mixin.ConnectionMixin;
import org.slf4j.Logger;

import java.net.InetSocketAddress;

public class ModDataHandler extends CommonNettyDataHandler {

@Inject
FloodgateLogger logger;

private net.minecraft.network.Connection networkManager;

@Inject
@Named("minecraftServer")
MinecraftServer minecraftServer;

private Connection player;
public ModDataHandler(
DataSeeker dataSeeker,
FloodgateDataHandler handshakeHandler,
FloodgateConfig config,
FloodgateLogger logger,
AttributeKey<Connection> connectionAttribute,
AttributeKey<String> kickMessageAttribute) {
super(
dataSeeker,
handshakeHandler,
config,
logger,
connectionAttribute,
kickMessageAttribute,
new PacketBlocker());
}

@Override
protected void setNewIp(Channel channel, InetSocketAddress newIp) {
((ConnectionMixin) this.networkManager).setAddress(newIp);
}

@Override
protected Object setHostname(Object handshakePacket, String hostname) {
// While it would be ideal to simply create a new handshake packet, the packet constructor
// does not allow us to set the protocol version
((ClientIntentionPacketMixinInterface) handshakePacket).setAddress(hostname);
return handshakePacket;
}

@Override
protected boolean shouldRemoveHandler(FloodgateDataHandler.HandleResult result) {
player = result.joinResult().connection();

if (getKickMessage() != null) {
// we also have to keep this handler if we want to kick then with a disconnect message
return false;
} else if (player == null) {
// player is not a Floodgate player
return true;
}

if (!result.joinResult().shouldDisconnect()) {
logger.info("Floodgate player who is logged in as {} {} joined",
player.javaUsername(), player.javaUuid());
}

// Handler will be removed after the login hello packet is handled
return false;
}

@Override
protected boolean channelRead(Object packet) throws Exception {
if (packet instanceof ClientIntentionPacket intentionPacket) {
ctx.pipeline().addAfter("splitter", "floodgate_packet_blocker", blocker);
networkManager = (net.minecraft.network.Connection) ctx.channel().pipeline().get("packet_handler");
handle(packet, intentionPacket.hostName());
return false;
}
return !checkAndHandleLogin(packet);
}

private boolean checkAndHandleLogin(Object packet) {
if (packet instanceof ServerboundHelloPacket) {
String kickMessage = getKickMessage();
if (kickMessage != null) {
networkManager.disconnect(Component.nullToEmpty(kickMessage));
return true;
}

// we have to fake the offline player (login) cycle
if (!(networkManager.getPacketListener() instanceof ServerLoginPacketListenerImpl packetListener)) {
// player is not in the login state, abort
ctx.pipeline().remove(this);
return true;
}

GameProfile gameProfile = new GameProfile(player.javaUuid(), player.javaUsername());

if (player.isLinked() && player.javaUuid().version() == 4) {
verifyLinkedPlayerAsync(packetListener, gameProfile);
} else {
packetListener.startClientVerification(gameProfile);
}

ctx.pipeline().remove(this);
return true;
}
return false;
}

/**
* Starts a new thread that fetches the linked player's textures,
* and then starts client verification with the more accurate game profile.
*
* @param packetListener the login packet listener for this connection
* @param gameProfile the player's initial profile. it will NOT be mutated.
*/
private void verifyLinkedPlayerAsync(ServerLoginPacketListenerImpl packetListener, GameProfile gameProfile) {
Thread texturesThread = new Thread("Bedrock Linked Player Texture Download") {
@Override
public void run() {
GameProfile effectiveProfile = gameProfile;
try {
MinecraftSessionService service = minecraftServer.getSessionService();
effectiveProfile = service.fetchProfile(effectiveProfile.getId(), true).profile();
} catch (Exception e) {
logger.error("Unable to get Bedrock linked player textures for " + effectiveProfile.getName(), e);
}
packetListener.startClientVerification(effectiveProfile);
}
};
texturesThread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler((Logger) logger));
texturesThread.start();
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
super.exceptionCaught(ctx, cause);
if (config.debug()) {
cause.printStackTrace();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.geysermc.floodgate.mod.inject;

import io.netty.channel.*;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.floodgate.api.logger.FloodgateLogger;
import org.geysermc.floodgate.core.inject.CommonPlatformInjector;

@Singleton
public class ModInjector extends CommonPlatformInjector {

@Inject FloodgateLogger logger;

private static ModInjector instance;

@Override
public void inject() throws Exception {
// handled by Mixin
}
public void injectClient(ChannelFuture future) {
future.channel().pipeline().addFirst("floodgate-init", new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(@NonNull ChannelHandlerContext ctx, @NonNull Object msg) throws Exception {
super.channelRead(ctx, msg);

Channel channel = (Channel) msg;
channel.pipeline().addLast(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(@NonNull Channel channel) {
injectAddonsCall(channel, false);
addInjectedClient(channel);
channel.closeFuture().addListener(listener -> {
channelClosedCall(channel);
removeInjectedClient(channel);
});
}
});
}
});
}

@Override
public boolean canRemoveInjection() {
return false;
}

@Override
public void removeInjection() throws Exception {
// not needed
}

@Override
public boolean isInjected() {
return true; // handled by Mixin
}

public static ModInjector getInstance() {
return instance;
}

public static void setInstance(ModInjector injector) {
instance = injector;
}
}
Loading