mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2026-01-06 15:42:03 +00:00
Couple more changes
This commit is contained in:
@@ -1,9 +1,19 @@
|
||||
plugins {
|
||||
id("floodgate.base-conventions")
|
||||
id("floodgate.shadow-conventions")
|
||||
id("architectury-plugin")
|
||||
id("dev.architectury.loom")
|
||||
}
|
||||
|
||||
configurations {
|
||||
create("includeTransitive").isTransitive = true
|
||||
create("shadowBundle") {
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
isTransitive = false
|
||||
}
|
||||
}
|
||||
|
||||
architectury {
|
||||
minecraft = libs.versions.minecraft.version.get()
|
||||
}
|
||||
@@ -18,6 +28,16 @@ indra {
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
shadowJar {
|
||||
// Mirrors the example fabric project, otherwise tons of dependencies are shaded that shouldn't be
|
||||
configurations = listOf(project.configurations.getByName("shadowBundle"))
|
||||
// The remapped shadowJar is the final desired mod jar
|
||||
archiveVersion.set(project.version.toString())
|
||||
archiveClassifier.set("shaded")
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft(libs.minecraft)
|
||||
mappings(loom.officialMojangMappings())
|
||||
|
||||
34
fabric/base/build.gradle.kts
Normal file
34
fabric/base/build.gradle.kts
Normal file
@@ -0,0 +1,34 @@
|
||||
plugins {
|
||||
id("floodgate.modded-conventions")
|
||||
}
|
||||
|
||||
architectury {
|
||||
platformSetupLoomIde()
|
||||
fabric()
|
||||
}
|
||||
|
||||
// Used to extend runtime/compile classpaths
|
||||
val common: Configuration by configurations.creating
|
||||
// Needed to read mixin config in the runServer task, and for the architectury transformer
|
||||
// (e.g. the @ExpectPlatform annotation)
|
||||
val developmentFabric: Configuration = configurations.getByName("developmentFabric")
|
||||
//// Our custom transitive include configuration
|
||||
//val includeTransitive: Configuration = configurations.getByName("includeTransitive")
|
||||
|
||||
configurations {
|
||||
compileClasspath.get().extendsFrom(configurations["common"])
|
||||
runtimeClasspath.get().extendsFrom(configurations["common"])
|
||||
developmentFabric.extendsFrom(configurations["common"])
|
||||
}
|
||||
|
||||
dependencies {
|
||||
modImplementation(libs.fabric.loader)
|
||||
modApi(libs.fabric.api)
|
||||
// "namedElements" configuration should be used to depend on different loom projects
|
||||
common(project(":mod", configuration = "namedElements"))
|
||||
// Bundle transformed classes of the common module for production mod jar
|
||||
shadowBundle(project(path = ":mod", configuration = "transformProductionFabric"))
|
||||
modImplementation(libs.cloud.fabric)
|
||||
|
||||
compileOnlyApi(projects.isolation)
|
||||
}
|
||||
@@ -4,10 +4,6 @@ import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
public class ModMixinConfigPluginImpl {
|
||||
|
||||
public static boolean isGeyserLoaded() {
|
||||
return FabricLoader.getInstance().isModLoaded("geyser-fabric");
|
||||
}
|
||||
|
||||
public static boolean applyProxyFix() {
|
||||
return FabricLoader.getInstance().isModLoaded("fabricproxy-lite");
|
||||
}
|
||||
|
||||
@@ -1,45 +1,41 @@
|
||||
package org.geysermc.floodgate.platform.fabric;
|
||||
|
||||
import io.micronaut.context.ApplicationContext;
|
||||
import io.micronaut.inject.qualifiers.Qualifiers;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import net.kyori.adventure.platform.modcommon.MinecraftServerAudiences;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.floodgate.core.module.PluginMessageModule;
|
||||
import org.geysermc.floodgate.core.module.ServerCommonModule;
|
||||
import org.geysermc.floodgate.mod.FloodgateMod;
|
||||
import org.geysermc.floodgate.mod.util.ModTemplateReader;
|
||||
import org.geysermc.floodgate.platform.fabric.module.FabricCommandModule;
|
||||
import org.geysermc.floodgate.platform.fabric.module.FabricPlatformModule;
|
||||
import org.geysermc.floodgate.isolation.library.LibraryManager;
|
||||
import org.geysermc.floodgate.mod.ModPlatform;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public final class FabricFloodgateMod extends FloodgateMod implements ModInitializer {
|
||||
public final class FabricFloodgateMod extends ModPlatform {
|
||||
|
||||
private ModContainer container;
|
||||
private final ModContainer container;
|
||||
|
||||
public FabricFloodgateMod(LibraryManager manager, ModContainer container) {
|
||||
super(manager);
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
container = FabricLoader.getInstance().getModContainer("floodgate").orElseThrow();
|
||||
init(
|
||||
new ServerCommonModule(
|
||||
FabricLoader.getInstance().getConfigDir().resolve("floodgate"),
|
||||
new ModTemplateReader()
|
||||
),
|
||||
new FabricPlatformModule(),
|
||||
new FabricCommandModule(),
|
||||
new PluginMessageModule()
|
||||
protected void onContextCreated(ApplicationContext context) {
|
||||
super.onContextCreated(context);
|
||||
context.registerSingleton(container)
|
||||
.registerSingleton(
|
||||
Path.class,
|
||||
FabricLoader.getInstance().getConfigDir().resolve("floodgate"),
|
||||
Qualifiers.byName("dataDirectory")
|
||||
);
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(this::enable);
|
||||
|
||||
if (isClient()) {
|
||||
ClientLifecycleEvents.CLIENT_STOPPING.register($ -> this.disable());
|
||||
} else {
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register($ -> this.disable());
|
||||
}
|
||||
ServerLifecycleEvents.SERVER_STARTED.register((server) -> {
|
||||
context.registerSingleton(server, false);
|
||||
context.registerSingleton(MinecraftServerAudiences.of(server), false);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.geysermc.floodgate.platform.fabric.listener;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerLoginConnectionEvents;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
import org.geysermc.floodgate.core.platform.listener.ListenerRegistration;
|
||||
import org.geysermc.floodgate.mod.listener.ModEventListener;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.geysermc.floodgate.platform.fabric.module;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import jakarta.inject.Singleton;
|
||||
import lombok.SneakyThrows;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import org.geysermc.floodgate.core.module.CommandModule;
|
||||
|
||||
@@ -9,47 +9,53 @@ import org.geysermc.floodgate.mod.pluginmessage.payloads.PacketPayload;
|
||||
import org.geysermc.floodgate.mod.pluginmessage.payloads.SkinPayload;
|
||||
import org.geysermc.floodgate.mod.pluginmessage.payloads.TransferPayload;
|
||||
|
||||
public class FabricPluginMessageRegistration implements PluginMessageRegistration {
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class FabricPluginMessageRegistration implements PluginMessageRegistration {
|
||||
|
||||
@Override
|
||||
public void register(PluginMessageChannel channel) {
|
||||
switch (channel.getIdentifier()) {
|
||||
case "floodgate:form" -> {
|
||||
PayloadTypeRegistry.playC2S().register(FormPayload.TYPE, FormPayload.STREAM_CODEC);
|
||||
PayloadTypeRegistry.playS2C().register(FormPayload.TYPE, FormPayload.STREAM_CODEC);
|
||||
ServerPlayNetworking.registerGlobalReceiver(FormPayload.TYPE,
|
||||
((payload, context) -> channel.handleServerCall(
|
||||
payload.data(),
|
||||
context.player().getUUID(),
|
||||
context.player().getGameProfile().getName())));
|
||||
}
|
||||
case "floodgate:packet" -> {
|
||||
PayloadTypeRegistry.playC2S().register(PacketPayload.TYPE, PacketPayload.STREAM_CODEC);
|
||||
PayloadTypeRegistry.playS2C().register(PacketPayload.TYPE, PacketPayload.STREAM_CODEC);
|
||||
ServerPlayNetworking.registerGlobalReceiver(PacketPayload.TYPE,
|
||||
((payload, context) -> channel.handleServerCall(
|
||||
payload.data(),
|
||||
context.player().getUUID(),
|
||||
context.player().getGameProfile().getName())));
|
||||
}
|
||||
case "floodgate:skin" -> {
|
||||
PayloadTypeRegistry.playC2S().register(SkinPayload.TYPE, SkinPayload.STREAM_CODEC);
|
||||
PayloadTypeRegistry.playS2C().register(SkinPayload.TYPE, SkinPayload.STREAM_CODEC);
|
||||
ServerPlayNetworking.registerGlobalReceiver(SkinPayload.TYPE,
|
||||
((payload, context) -> channel.handleServerCall(
|
||||
payload.data(),
|
||||
context.player().getUUID(),
|
||||
context.player().getGameProfile().getName())));
|
||||
}
|
||||
case "floodgate:transfer" -> {
|
||||
PayloadTypeRegistry.playC2S().register(TransferPayload.TYPE, TransferPayload.STREAM_CODEC);
|
||||
PayloadTypeRegistry.playS2C().register(TransferPayload.TYPE, TransferPayload.STREAM_CODEC);
|
||||
ServerPlayNetworking.registerGlobalReceiver(TransferPayload.TYPE,
|
||||
((payload, context) -> channel.handleServerCall(
|
||||
payload.data(),
|
||||
context.player().getUUID(),
|
||||
context.player().getGameProfile().getName())));
|
||||
}
|
||||
default -> throw new IllegalArgumentException("unknown channel: " + channel);
|
||||
final String id = channel.getIdentifier();
|
||||
|
||||
switch (id) {
|
||||
case "floodgate:form" ->
|
||||
registerBoth(channel, FormPayload.TYPE, FormPayload.STREAM_CODEC, FormPayload::data);
|
||||
case "floodgate:packet" ->
|
||||
registerBoth(channel, PacketPayload.TYPE, PacketPayload.STREAM_CODEC, PacketPayload::data);
|
||||
case "floodgate:skin" ->
|
||||
registerBoth(channel, SkinPayload.TYPE, SkinPayload.STREAM_CODEC, SkinPayload::data);
|
||||
case "floodgate:transfer" ->
|
||||
registerBoth(channel, TransferPayload.TYPE, TransferPayload.STREAM_CODEC, TransferPayload::data);
|
||||
default -> throw new IllegalArgumentException("Unknown channel: " + id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers payload type/codec for both directions and wires a global receiver that
|
||||
* forwards to the PluginMessageChannel.
|
||||
*/
|
||||
private static <T extends CustomPacketPayload> void registerBoth(
|
||||
PluginMessageChannel channel,
|
||||
CustomPacketPayload.Type<T> type,
|
||||
StreamCodec<? super RegistryFriendlyByteBuf, T> codec,
|
||||
Function<T, byte[]> dataExtractor
|
||||
) {
|
||||
// Bidirectional registration
|
||||
PayloadTypeRegistry.playC2S().register(type, codec);
|
||||
PayloadTypeRegistry.playS2C().register(type, codec);
|
||||
|
||||
// Single handler that delegates to channel.handleServerCall(...)
|
||||
ServerPlayNetworking.registerGlobalReceiver(
|
||||
type,
|
||||
(payload, context) -> channel.handleServerCall(
|
||||
dataExtractor.apply(payload),
|
||||
context.player().getUUID(),
|
||||
context.player().getGameProfile().getName()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package org.geysermc.floodgate.platform.fabric.pluginmessage;
|
||||
|
||||
import io.micronaut.context.BeanProvider;
|
||||
import jakarta.inject.Inject;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.geysermc.floodgate.core.platform.pluginmessage.PluginMessageUtils;
|
||||
import org.geysermc.floodgate.mod.MinecraftServerHolder;
|
||||
import org.geysermc.floodgate.mod.pluginmessage.payloads.FormPayload;
|
||||
import org.geysermc.floodgate.mod.pluginmessage.payloads.PacketPayload;
|
||||
import org.geysermc.floodgate.mod.pluginmessage.payloads.SkinPayload;
|
||||
@@ -15,10 +17,13 @@ import java.util.UUID;
|
||||
|
||||
public class FabricPluginMessageUtils extends PluginMessageUtils {
|
||||
|
||||
@Inject
|
||||
private BeanProvider<MinecraftServer> server;
|
||||
|
||||
@Override
|
||||
public boolean sendMessage(UUID uuid, String channel, byte[] data) {
|
||||
try {
|
||||
ServerPlayer player = MinecraftServerHolder.get().getPlayerList().getPlayer(uuid);
|
||||
ServerPlayer player = server.get().getPlayerList().getPlayer(uuid);
|
||||
final CustomPacketPayload payload;
|
||||
switch (channel) {
|
||||
case "floodgate:form" -> payload = new FormPayload(data);
|
||||
|
||||
@@ -7,46 +7,35 @@ architectury {
|
||||
fabric()
|
||||
}
|
||||
|
||||
// Used to extend runtime/compile classpaths
|
||||
val common: Configuration by configurations.creating
|
||||
// Needed to read mixin config in the runServer task, and for the architectury transformer
|
||||
// (e.g. the @ExpectPlatform annotation)
|
||||
val developmentFabric: Configuration = configurations.getByName("developmentFabric")
|
||||
// Our custom transitive include configuration
|
||||
val includeTransitive: Configuration = configurations.getByName("includeTransitive")
|
||||
|
||||
configurations {
|
||||
compileClasspath.get().extendsFrom(configurations["common"])
|
||||
runtimeClasspath.get().extendsFrom(configurations["common"])
|
||||
developmentFabric.extendsFrom(configurations["common"])
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// FIXME why does it break when this is set to api scope???
|
||||
compileOnlyApi(projects.isolation)
|
||||
|
||||
modImplementation(libs.fabric.loader)
|
||||
modApi(libs.fabric.api)
|
||||
// "namedElements" configuration should be used to depend on different loom projects
|
||||
common(project(":mod", configuration = "namedElements")) { isTransitive = false }
|
||||
// Bundle transformed classes of the common module for production mod jar
|
||||
shadow(project(path = ":mod", configuration = "transformProductionFabric")) {
|
||||
isTransitive = false
|
||||
}
|
||||
|
||||
includeTransitive(libs.floodgate.core)
|
||||
implementation(libs.floodgate.core)
|
||||
implementation(libs.guice)
|
||||
|
||||
modImplementation(libs.cloud.fabric)
|
||||
include(libs.cloud.fabric)
|
||||
include(libs.fabric.permissions.api)
|
||||
}
|
||||
|
||||
tasks {
|
||||
remapJar {
|
||||
archiveBaseName.set("floodgate-fabric")
|
||||
jar {
|
||||
dependsOn(":fabric-base:build", configurations.runtimeClasspath)
|
||||
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) })
|
||||
|
||||
archiveBaseName = "floodgate-${project.name}"
|
||||
archiveVersion = ""
|
||||
archiveClassifier = ""
|
||||
|
||||
val libsDir = project.projects
|
||||
.fabricBase.dependencyProject
|
||||
.layout.buildDirectory.dir("libs")
|
||||
|
||||
from(libsDir) {
|
||||
include("floodgate-fabric-base.jar")
|
||||
rename("floodgate-fabric-base.jar", "platform-base.jar")
|
||||
into("bundled/")
|
||||
}
|
||||
}
|
||||
|
||||
// modrinth {
|
||||
// loaders.add("fabric")
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -23,27 +23,34 @@
|
||||
* @link https://github.com/GeyserMC/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.spigot;
|
||||
package org.geysermc.floodgate.fabric;
|
||||
|
||||
import java.util.List;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import org.geysermc.floodgate.isolation.loader.PlatformHolder;
|
||||
import org.geysermc.floodgate.isolation.loader.PlatformLoader;
|
||||
|
||||
public final class IsolatedFabricMod implements ModInitializer {
|
||||
private PlatformHolder holder;
|
||||
private static final isServer = FabricLoader.getInstance().getEnvironmentType().equals(EnvType.SERVER);
|
||||
private static final boolean IS_SERVER = FabricLoader.getInstance().getEnvironmentType().equals(EnvType.SERVER);
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
PlatformHolder holder;
|
||||
try {
|
||||
var libsDirectory = getDataFolder().toPath().resolve("libs");
|
||||
ModContainer container = FabricLoader.getInstance().getModContainer("floodgate").orElseThrow();
|
||||
var libsDirectory = FabricLoader.getInstance().getConfigDir().resolve("floodgate").resolve("libs");
|
||||
holder = PlatformLoader.loadDefault(getClass().getClassLoader(), libsDirectory);
|
||||
holder.init(List.of(ModContainer.class), List.of(this));
|
||||
holder.init(List.of(ModContainer.class), List.of(container));
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException("Failed to load Floodgate", exception);
|
||||
}
|
||||
|
||||
if (isServer) {
|
||||
if (IS_SERVER) {
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(($) -> {
|
||||
holder.enable();
|
||||
});
|
||||
@@ -54,7 +61,7 @@ public final class IsolatedFabricMod implements ModInitializer {
|
||||
}
|
||||
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register(($) -> {
|
||||
if (isServer) {
|
||||
if (IS_SERVER) {
|
||||
holder.shutdown();
|
||||
} else {
|
||||
holder.disable();
|
||||
@@ -9,13 +9,13 @@
|
||||
],
|
||||
"contact": {
|
||||
"website": "$url",
|
||||
"repo": "https://github.com/GeyserMC/Floodgate-Modded"
|
||||
"repo": "https://github.com/GeyserMC/Floodgate"
|
||||
},
|
||||
"license": "MIT",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"org.geysermc.floodgate.platform.fabric.FabricFloodgateMod"
|
||||
"org.geysermc.floodgate.fabric.IsolatedFabricMod"
|
||||
]
|
||||
},
|
||||
"accessWidener": "floodgate.accesswidener",
|
||||
@@ -0,0 +1 @@
|
||||
org.geysermc.floodgate.fabric.FabricPlatform
|
||||
@@ -1,9 +1,11 @@
|
||||
org.gradle.configureondemand=true
|
||||
org.gradle.caching=true
|
||||
org.gradle.parallel=true
|
||||
# TODO https://github.com/architectury/architectury-plugin/pull/56
|
||||
org.gradle.configuration-cache=false
|
||||
|
||||
group=org.geysermc
|
||||
id=floodgate
|
||||
description="Allows Bedrock players to join Java edition servers while keeping the server in online mode"
|
||||
version=3.0.0-SNAPSHOT
|
||||
micronautVersion=4.6.0
|
||||
micronautVersion=4.6.0
|
||||
|
||||
@@ -17,6 +17,7 @@ snakeyaml = "2.0"
|
||||
bstats = "3.0.3"
|
||||
adventure = "4.17.0"
|
||||
adventure-platform = "4.3.4"
|
||||
adventure-platform-modded = "6.6.0"
|
||||
avaje-http = "2.7"
|
||||
avaje-jsonb = "2.1"
|
||||
expiringmap = "0.5.11"
|
||||
@@ -48,7 +49,7 @@ fabric-permissions-api = "0.4.1-SNAPSHOT"
|
||||
neoforge-version = "21.6.11-beta"
|
||||
|
||||
# buildSrc
|
||||
indra = "3.1.3"
|
||||
indra = "3.2.0"
|
||||
shadow = "8.3.0"
|
||||
gradle-idea-ext = "1.1.7"
|
||||
checkerframework = "3.42.0"
|
||||
@@ -83,8 +84,9 @@ bstats = { module = "org.bstats:bstats-base", version.ref = "bstats" }
|
||||
adventure-api = { module = "net.kyori:adventure-api", version.ref = "adventure" }
|
||||
adventure-key = { module = "net.kyori:adventure-key", version.ref = "adventure" }
|
||||
adventure-text-minimessage = { module = "net.kyori:adventure-text-minimessage", version.ref = "adventure" }
|
||||
adventure-platform-bukkit = { module = "net.kyori:adventure-platform-bukkit", version.ref = "adventure-platform"}
|
||||
adventure-platform-bungee = { module = "net.kyori:adventure-platform-bungeecord", version.ref = "adventure-platform"}
|
||||
adventure-platform-bukkit = { module = "net.kyori:adventure-platform-bukkit", version.ref = "adventure-platform" }
|
||||
adventure-platform-bungee = { module = "net.kyori:adventure-platform-bungeecord", version.ref = "adventure-platform" }
|
||||
adventure-platform-modded = { module = "net.kyori:adventure-platform-mod-shared", version.ref = "adventure-platform-modded" }
|
||||
|
||||
micronaut-inject = { module = "io.micronaut:micronaut-inject" }
|
||||
micronaut-inject-java = { module = "io.micronaut:micronaut-inject-java" }
|
||||
|
||||
@@ -17,6 +17,8 @@ dependencies {
|
||||
annotationProcessor(libs.micronaut.inject.java)
|
||||
compileOnlyApi(projects.isolation)
|
||||
|
||||
modApi(libs.adventure.platform.modded)
|
||||
|
||||
compileOnly(libs.mixin)
|
||||
compileOnly(libs.asm)
|
||||
|
||||
|
||||
@@ -1,17 +1,27 @@
|
||||
package org.geysermc.floodgate.mod;
|
||||
|
||||
import io.micronaut.context.ApplicationContext;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.floodgate.core.FloodgatePlatform;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import org.geysermc.floodgate.isolation.library.LibraryManager;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public abstract class ModPlatform extends FloodgatePlatform {
|
||||
|
||||
protected ApplicationContext context;
|
||||
|
||||
protected ModPlatform(LibraryManager manager) {
|
||||
super(manager);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onContextCreated(ApplicationContext context) {
|
||||
context.registerSingleton(LoggerFactory.getLogger("floodgate"));
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public @Nullable abstract Path resourcePath(String file);
|
||||
|
||||
public abstract boolean isClient();
|
||||
|
||||
@@ -17,9 +17,9 @@ import org.geysermc.floodgate.core.util.Utils;
|
||||
|
||||
@Singleton
|
||||
public final class ModDataAddon implements InjectorAddon<Channel> {
|
||||
|
||||
@Inject
|
||||
DataSeeker dataSeeker;
|
||||
|
||||
@Inject
|
||||
FloodgateDataHandler handshakeHandler;
|
||||
|
||||
@@ -47,14 +47,6 @@ public final class ModDataAddon implements InjectorAddon<Channel> {
|
||||
channel.pipeline().addBefore(packetHandlerName, "floodgate_data_handler", dataHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChannelClosed(Channel channel) {
|
||||
FloodgatePlayer player = channel.attr(playerAttribute).get();
|
||||
if (player != null && api.setPendingRemove(player)) {
|
||||
logger.translatedInfo("floodgate.ingame.disconnect_name", player.getCorrectUsername());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoveInject(Channel channel) {
|
||||
Utils.removeHandler(channel.pipeline(), "floodgate_data_handler");
|
||||
|
||||
@@ -3,24 +3,25 @@ package org.geysermc.floodgate.mod.data;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import io.micronaut.context.BeanProvider;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.util.AttributeKey;
|
||||
import jakarta.inject.Inject;
|
||||
import net.kyori.adventure.platform.modcommon.MinecraftServerAudiences;
|
||||
import net.minecraft.DefaultUncaughtExceptionHandler;
|
||||
import net.minecraft.network.Connection;
|
||||
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.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.core.addon.data.CommonDataHandler;
|
||||
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.player.FloodgateHandshakeHandler;
|
||||
import org.geysermc.floodgate.core.player.FloodgateHandshakeHandler.HandshakeResult;
|
||||
import org.geysermc.floodgate.mod.MinecraftServerHolder;
|
||||
import org.geysermc.floodgate.core.connection.DataSeeker;
|
||||
import org.geysermc.floodgate.core.connection.FloodgateDataHandler;
|
||||
import org.geysermc.floodgate.core.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.mod.mixin.ClientIntentionPacketMixinInterface;
|
||||
import org.geysermc.floodgate.mod.mixin.ConnectionMixin;
|
||||
import org.slf4j.Logger;
|
||||
@@ -29,17 +30,33 @@ import java.net.InetSocketAddress;
|
||||
|
||||
public final class ModDataHandler extends CommonNettyDataHandler {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final FloodgateLogger logger;
|
||||
private Connection networkManager;
|
||||
private FloodgatePlayer player;
|
||||
// stellar, but, won't change this now
|
||||
private org.geysermc.api.connection.Connection connection;
|
||||
private boolean proxyData;
|
||||
|
||||
@Inject
|
||||
BeanProvider<MinecraftServer> server;
|
||||
|
||||
@Inject
|
||||
BeanProvider<MinecraftServerAudiences> audience;
|
||||
|
||||
public ModDataHandler(
|
||||
FloodgateHandshakeHandler handshakeHandler,
|
||||
DataSeeker dataSeeker,
|
||||
FloodgateDataHandler dataHandler,
|
||||
FloodgateConfig config,
|
||||
AttributeKey<String> kickMessageAttribute, FloodgateLogger logger) {
|
||||
super(handshakeHandler, config, kickMessageAttribute, new PacketBlocker());
|
||||
this.logger = logger;
|
||||
FloodgateLogger logger,
|
||||
AttributeKey<org.geysermc.api.connection.Connection> connectionAttribute,
|
||||
AttributeKey<net.kyori.adventure.text.Component> kickMessageAttribute) {
|
||||
super(
|
||||
dataSeeker,
|
||||
dataHandler,
|
||||
config,
|
||||
logger,
|
||||
connectionAttribute,
|
||||
kickMessageAttribute,
|
||||
new PacketBlocker()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,21 +73,18 @@ public final class ModDataHandler extends CommonNettyDataHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldRemoveHandler(HandshakeResult result) {
|
||||
player = result.getFloodgatePlayer();
|
||||
protected boolean shouldRemoveHandler(FloodgateDataHandler.HandleResult result) {
|
||||
connection = result.joinResult() != null ? result.joinResult().connection() : null;
|
||||
|
||||
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) {
|
||||
} else if (connection == null) {
|
||||
// player is not a Floodgate player
|
||||
return true;
|
||||
}
|
||||
|
||||
if (result.getResultType() == FloodgateHandshakeHandler.ResultType.SUCCESS) {
|
||||
logger.info("Floodgate player who is logged in as {} {} joined",
|
||||
player.getCorrectUsername(), player.getCorrectUniqueId());
|
||||
}
|
||||
// TODO proxy data handling...?
|
||||
|
||||
// Handler will be removed after the login hello packet is handled
|
||||
return false;
|
||||
@@ -89,9 +103,9 @@ public final class ModDataHandler extends CommonNettyDataHandler {
|
||||
|
||||
private boolean checkAndHandleLogin(Object packet) {
|
||||
if (packet instanceof ServerboundHelloPacket) {
|
||||
String kickMessage = getKickMessage();
|
||||
var kickMessage = getKickMessage();
|
||||
if (kickMessage != null) {
|
||||
Component message = Component.nullToEmpty(kickMessage);
|
||||
Component message = audience.get().asNative(kickMessage);
|
||||
// If possible, disconnect using the "proper" packet listener; otherwise there's no proper disconnect message
|
||||
if (networkManager.getPacketListener() instanceof ServerLoginPacketListenerImpl loginPacketListener) {
|
||||
loginPacketListener.disconnect(message);
|
||||
@@ -108,9 +122,9 @@ public final class ModDataHandler extends CommonNettyDataHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
GameProfile gameProfile = new GameProfile(player.getCorrectUniqueId(), player.getCorrectUsername());
|
||||
GameProfile gameProfile = new GameProfile(connection.javaUuid(), connection.javaUsername());
|
||||
|
||||
if (player.isLinked() && player.getCorrectUniqueId().version() == 4) {
|
||||
if (connection.isLinked() && connection.javaUuid().version() == 4) {
|
||||
verifyLinkedPlayerAsync(packetListener, gameProfile);
|
||||
} else {
|
||||
packetListener.startClientVerification(gameProfile);
|
||||
@@ -135,7 +149,7 @@ public final class ModDataHandler extends CommonNettyDataHandler {
|
||||
public void run() {
|
||||
GameProfile effectiveProfile = gameProfile;
|
||||
try {
|
||||
MinecraftSessionService service = MinecraftServerHolder.get().getSessionService();
|
||||
MinecraftSessionService service = server.get().getSessionService();
|
||||
effectiveProfile = service.fetchProfile(effectiveProfile.getId(), true).profile();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Unable to get Bedrock linked player textures for " + effectiveProfile.getName(), e);
|
||||
@@ -151,7 +165,7 @@ public final class ModDataHandler extends CommonNettyDataHandler {
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||
super.exceptionCaught(ctx, cause);
|
||||
if (config.isDebug()) {
|
||||
if (config.debug()) {
|
||||
LOGGER.error("Exception caught in FabricDataHandler", cause);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package org.geysermc.floodgate.mod.inject;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@@ -9,26 +8,22 @@ import io.netty.channel.ChannelInitializer;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.core.inject.CommonPlatformInjector;
|
||||
import org.geysermc.floodgate.core.inject.Netty4PlatformInjector;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class ModInjector extends CommonPlatformInjector {
|
||||
public final class ModInjector extends Netty4PlatformInjector {
|
||||
|
||||
public static ModInjector INSTANCE = new ModInjector();
|
||||
|
||||
@Getter private final boolean injected = true;
|
||||
|
||||
@Inject private FloodgateLogger logger;
|
||||
|
||||
@Override
|
||||
public void inject() throws Exception {
|
||||
//no-op
|
||||
//no-op, mixins go brrrrrr
|
||||
}
|
||||
|
||||
public void injectClient(ChannelFuture future) {
|
||||
if (future.channel().pipeline().names().contains("floodgate-init")) {
|
||||
logger.debug("Tried to inject twice!");
|
||||
if (isInjected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -57,7 +52,7 @@ public final class ModInjector extends CommonPlatformInjector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeInjection() throws Exception {
|
||||
public void removeInjection() {
|
||||
//no-op
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +1,32 @@
|
||||
package org.geysermc.floodgate.mod.listener;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.core.util.LanguageManager;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import org.geysermc.floodgate.core.connection.ConnectionManager;
|
||||
|
||||
import java.util.UUID;
|
||||
import org.geysermc.floodgate.core.util.LanguageManager;
|
||||
|
||||
public final class ModEventListener {
|
||||
@Inject private FloodgateApi api;
|
||||
@Inject private FloodgateLogger logger;
|
||||
@Inject private LanguageManager languageManager;
|
||||
|
||||
@Inject
|
||||
LanguageManager languageManager;
|
||||
|
||||
@Inject
|
||||
ConnectionManager connectionManager;
|
||||
|
||||
public void onPlayerJoin(UUID uuid) {
|
||||
FloodgatePlayer player = api.getPlayer(uuid);
|
||||
if (player != null) {
|
||||
logger.translatedInfo(
|
||||
"floodgate.ingame.login_name",
|
||||
player.getCorrectUsername(), player.getCorrectUniqueId()
|
||||
);
|
||||
languageManager.loadLocale(player.getLanguageCode());
|
||||
// TODO this might be called late on fabric
|
||||
var connection = connectionManager.findPendingConnection(uuid);
|
||||
if (connection == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
languageManager.loadLocale(connection.languageCode());
|
||||
connectionManager.addAcceptedConnection(connection);
|
||||
}
|
||||
|
||||
public void onPlayerQuit(UUID uuid) {
|
||||
connectionManager.removeConnection(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
package org.geysermc.floodgate.mod.logger;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.core.config.Configurator;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.core.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.core.util.LanguageManager;
|
||||
|
||||
import static org.geysermc.floodgate.core.util.MessageFormatter.format;
|
||||
|
||||
@Singleton
|
||||
public final class Log4jFloodgateLogger implements FloodgateLogger {
|
||||
@Inject
|
||||
@Named("logger")
|
||||
private Logger logger;
|
||||
private LanguageManager languageManager;
|
||||
|
||||
@Inject
|
||||
private void init(LanguageManager languageManager, FloodgateConfig config) {
|
||||
this.languageManager = languageManager;
|
||||
if (config.isDebug() && !logger.isDebugEnabled()) {
|
||||
Configurator.setLevel(logger.getName(), Level.DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String message, Object... args) {
|
||||
logger.error(message, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(String message, Throwable throwable, Object... args) {
|
||||
logger.error(format(message, args), throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String message, Object... args) {
|
||||
logger.warn(message, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String message, Object... args) {
|
||||
logger.info(message, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translatedInfo(String message, Object... args) {
|
||||
logger.info(languageManager.getLogString(message, args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String message, Object... args) {
|
||||
logger.debug(message, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(String message, Object... args) {
|
||||
logger.trace(message, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebug() {
|
||||
return logger.isDebugEnabled();
|
||||
}
|
||||
}
|
||||
@@ -1,55 +1,11 @@
|
||||
package org.geysermc.floodgate.mod.module;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import com.google.inject.name.Names;
|
||||
import io.micronaut.context.annotation.Bean;
|
||||
import jakarta.inject.Named;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.core.inject.CommonPlatformInjector;
|
||||
import org.geysermc.floodgate.core.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.core.platform.util.PlatformUtils;
|
||||
import org.geysermc.floodgate.core.skin.SkinApplier;
|
||||
import org.geysermc.floodgate.core.util.LanguageManager;
|
||||
import org.geysermc.floodgate.mod.FloodgateMod;
|
||||
import org.geysermc.floodgate.mod.inject.ModInjector;
|
||||
import org.geysermc.floodgate.mod.logger.Log4jFloodgateLogger;
|
||||
import org.geysermc.floodgate.mod.pluginmessage.ModSkinApplier;
|
||||
import org.geysermc.floodgate.mod.util.ModCommandUtil;
|
||||
import org.geysermc.floodgate.mod.util.ModPlatformUtils;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public abstract class ModPlatformModule extends AbstractModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public CommandUtil commandUtil(
|
||||
FloodgateApi api,
|
||||
FloodgateLogger logger,
|
||||
LanguageManager languageManager) {
|
||||
return new ModCommandUtil(languageManager, api, logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(PlatformUtils.class).to(ModPlatformUtils.class);
|
||||
bind(Logger.class).annotatedWith(Names.named("logger")).toInstance(LogManager.getLogger("floodgate"));
|
||||
bind(FloodgateLogger.class).to(Log4jFloodgateLogger.class);
|
||||
}
|
||||
|
||||
/*
|
||||
DebugAddon / PlatformInjector
|
||||
*/
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public CommonPlatformInjector platformInjector() {
|
||||
return ModInjector.INSTANCE;
|
||||
}
|
||||
public abstract class ModPlatformModule {
|
||||
|
||||
@Provides
|
||||
@Named("packetEncoder")
|
||||
@@ -63,15 +19,11 @@ public abstract class ModPlatformModule extends AbstractModule {
|
||||
return FloodgateMod.INSTANCE.isClient() ? "inbound_config" : "decoder" ;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Bean
|
||||
@Named("packetHandler")
|
||||
public String packetHandler() {
|
||||
return "packet_handler";
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public SkinApplier skinApplier() {
|
||||
return new ModSkinApplier();
|
||||
}
|
||||
// TODO implementation name
|
||||
}
|
||||
|
||||
@@ -2,15 +2,16 @@ package org.geysermc.floodgate.mod.pluginmessage;
|
||||
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
import io.micronaut.context.BeanProvider;
|
||||
import jakarta.inject.Inject;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.api.connection.Connection;
|
||||
import org.geysermc.floodgate.core.skin.SkinApplier;
|
||||
import org.geysermc.floodgate.mod.MinecraftServerHolder;
|
||||
import org.geysermc.floodgate.mod.mixin.ChunkMapMixin;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -19,12 +20,16 @@ import static org.geysermc.floodgate.api.event.skin.SkinApplyEvent.SkinData;
|
||||
|
||||
public final class ModSkinApplier implements SkinApplier {
|
||||
|
||||
@Inject
|
||||
BeanProvider<MinecraftServer> server;
|
||||
|
||||
@Override
|
||||
public void applySkin(@NonNull FloodgatePlayer floodgatePlayer, @NonNull SkinData skinData) {
|
||||
MinecraftServerHolder.get().execute(() -> {
|
||||
ServerPlayer bedrockPlayer = MinecraftServerHolder.get().getPlayerList()
|
||||
.getPlayer(floodgatePlayer.getCorrectUniqueId());
|
||||
public void applySkin(@NonNull Connection connection, @NonNull SkinData skinData) {
|
||||
server.get().execute(() -> {
|
||||
ServerPlayer bedrockPlayer = server.get().getPlayerList()
|
||||
.getPlayer(connection.javaUuid());
|
||||
if (bedrockPlayer == null) {
|
||||
// TODO apply skins with delay???
|
||||
// Disconnected probably?
|
||||
return;
|
||||
}
|
||||
@@ -35,10 +40,10 @@ public final class ModSkinApplier implements SkinApplier {
|
||||
properties.removeAll("textures");
|
||||
properties.put("textures", new Property("textures", skinData.value(), skinData.signature()));
|
||||
|
||||
ChunkMap tracker = ((ServerLevel) bedrockPlayer.level).getChunkSource().chunkMap;
|
||||
ChunkMap tracker = bedrockPlayer.level().getChunkSource().chunkMap;
|
||||
ChunkMap.TrackedEntity entry = ((ChunkMapMixin) tracker).getEntityMap().get(bedrockPlayer.getId());
|
||||
// Skin is applied - now it's time to refresh the player for everyone.
|
||||
for (ServerPlayer otherPlayer : MinecraftServerHolder.get().getPlayerList().getPlayers()) {
|
||||
for (ServerPlayer otherPlayer : server.get().getPlayerList().getPlayers()) {
|
||||
boolean samePlayer = otherPlayer == bedrockPlayer;
|
||||
if (!samePlayer) {
|
||||
// TrackedEntity#broadcastRemoved doesn't actually remove them from seenBy
|
||||
@@ -51,7 +56,7 @@ public final class ModSkinApplier implements SkinApplier {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bedrockPlayer.level == otherPlayer.level) {
|
||||
if (bedrockPlayer.level() == otherPlayer.level()) {
|
||||
entry.updatePlayer(otherPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +1,48 @@
|
||||
package org.geysermc.floodgate.mod.util;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.micronaut.context.BeanProvider;
|
||||
import jakarta.inject.Inject;
|
||||
import lombok.Setter;
|
||||
import net.kyori.adventure.platform.modcommon.MinecraftServerAudiences;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.players.UserWhiteListEntry;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.api.GeyserApiBase;
|
||||
import org.geysermc.floodgate.core.connection.audience.UserAudience;
|
||||
import org.geysermc.floodgate.core.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.core.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.core.player.UserAudience;
|
||||
import org.geysermc.floodgate.core.util.LanguageManager;
|
||||
import org.geysermc.floodgate.mod.MinecraftServerHolder;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class ModCommandUtil extends CommandUtil {
|
||||
private final FloodgateLogger logger;
|
||||
private UserAudience console;
|
||||
@Setter
|
||||
private CommandManager<UserAudience> commandManager;
|
||||
|
||||
public ModCommandUtil(LanguageManager manager, FloodgateApi api, FloodgateLogger logger) {
|
||||
BeanProvider<MinecraftServer> server;
|
||||
BeanProvider<MinecraftServerAudiences> audience;
|
||||
|
||||
@Inject
|
||||
public ModCommandUtil(
|
||||
LanguageManager manager,
|
||||
GeyserApiBase api,
|
||||
BeanProvider<MinecraftServer> server,
|
||||
BeanProvider<MinecraftServerAudiences> audience) {
|
||||
super(manager, api);
|
||||
this.logger = logger;
|
||||
this.server = server;
|
||||
this.audience = audience;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull UserAudience getUserAudience(final @NonNull Object sourceObj) {
|
||||
if (!(sourceObj instanceof CommandSourceStack stack)) {
|
||||
throw new IllegalArgumentException();
|
||||
throw new IllegalArgumentException("Source has to be a CommandSourceStack");
|
||||
}
|
||||
if (stack.getEntity() == null) {
|
||||
if (console != null) {
|
||||
@@ -58,19 +68,19 @@ public final class ModCommandUtil extends CommandUtil {
|
||||
|
||||
@Override
|
||||
public Object getPlayerByUuid(@NonNull UUID uuid) {
|
||||
ServerPlayer player = MinecraftServerHolder.get().getPlayerList().getPlayer(uuid);
|
||||
ServerPlayer player = server.get().getPlayerList().getPlayer(uuid);
|
||||
return player != null ? player : uuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPlayerByUsername(@NonNull String username) {
|
||||
ServerPlayer player = MinecraftServerHolder.get().getPlayerList().getPlayerByName(username);
|
||||
ServerPlayer player = server.get().getPlayerList().getPlayerByName(username);
|
||||
return player != null ? player : username;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<?> getOnlinePlayers() {
|
||||
return MinecraftServerHolder.get().getPlayerList().getPlayers();
|
||||
return server.get().getPlayerList().getPlayers();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,35 +89,32 @@ public final class ModCommandUtil extends CommandUtil {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(Object target, String message) {
|
||||
public void sendMessage(Object target, net.kyori.adventure.text.Component message) {
|
||||
CommandSourceStack commandSource = (CommandSourceStack) target;
|
||||
if (commandSource.getEntity() instanceof ServerPlayer) {
|
||||
MinecraftServerHolder.get().execute(() -> ((ServerPlayer) commandSource.getEntity())
|
||||
.displayClientMessage(Component.literal(message), false));
|
||||
} else {
|
||||
// Console?
|
||||
logger.info(message);
|
||||
server.get().execute(() -> ((ServerPlayer) commandSource.getEntity())
|
||||
.displayClientMessage(audience.get().asNative(message), false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void kickPlayer(Object o, String message) {
|
||||
public void kickPlayer(Object o, net.kyori.adventure.text.Component message) {
|
||||
if (o instanceof ServerPlayer player) {
|
||||
player.connection.disconnect(Component.literal(message));
|
||||
player.connection.disconnect(audience.get().asNative(message));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean whitelistPlayer(UUID uuid, String username) {
|
||||
GameProfile profile = new GameProfile(uuid, username);
|
||||
MinecraftServerHolder.get().getPlayerList().getWhiteList().add(new UserWhiteListEntry(profile));
|
||||
server.get().getPlayerList().getWhiteList().add(new UserWhiteListEntry(profile));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removePlayerFromWhitelist(UUID uuid, String username) {
|
||||
GameProfile profile = new GameProfile(uuid, username);
|
||||
MinecraftServerHolder.get().getPlayerList().getWhiteList().remove(profile);
|
||||
server.get().getPlayerList().getWhiteList().remove(profile);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
package org.geysermc.floodgate.mod.util;
|
||||
|
||||
import io.micronaut.context.BeanProvider;
|
||||
import jakarta.inject.Inject;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.geysermc.floodgate.core.platform.util.PlatformUtils;
|
||||
import org.geysermc.floodgate.mod.MinecraftServerHolder;
|
||||
|
||||
public class ModPlatformUtils extends PlatformUtils {
|
||||
|
||||
@Inject
|
||||
BeanProvider<MinecraftServer> minecraftServer;
|
||||
|
||||
@Override
|
||||
public AuthType authType() {
|
||||
return MinecraftServerHolder.get().usesAuthentication() ? AuthType.ONLINE : AuthType.OFFLINE;
|
||||
// TODO proxied auth type
|
||||
return minecraftServer.get().usesAuthentication() ? AuthType.ONLINE : AuthType.OFFLINE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -17,6 +24,6 @@ public class ModPlatformUtils extends PlatformUtils {
|
||||
|
||||
@Override
|
||||
public String serverImplementationName() {
|
||||
return MinecraftServerHolder.get().getServerModName();
|
||||
return minecraftServer.get().getServerModName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ dependencies {
|
||||
|
||||
neoForge(libs.neoforge)
|
||||
// "namedElements" configuration should be used to depend on different loom projects
|
||||
common(project(":mod", configuration = "namedElements")) { isTransitive = false }
|
||||
common(project(":mod", configuration = "namedElements"))
|
||||
// Bundle transformed classes of the common module for production mod jar
|
||||
shadow(project(path = ":mod", configuration = "transformProductionNeoForge")) { isTransitive = false }
|
||||
|
||||
@@ -54,8 +54,4 @@ tasks {
|
||||
atAccessWideners.add("floodgate.accesswidener")
|
||||
archiveBaseName.set("floodgate-neoforge")
|
||||
}
|
||||
|
||||
// modrinth {
|
||||
// loaders.add("neoforge")
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ arrayOf("common", "netty4").forEach {
|
||||
project(id).projectDir = file("core/$it")
|
||||
}
|
||||
|
||||
arrayOf("bungee", "spigot", "velocity").forEach { platform ->
|
||||
arrayOf("bungee", "spigot", "velocity", "fabric").forEach { platform ->
|
||||
arrayOf("base", "isolated").forEach {
|
||||
var id = ":$platform-$it"
|
||||
// isolated is the new default
|
||||
|
||||
Reference in New Issue
Block a user