diff --git a/build.gradle b/build.gradle deleted file mode 100644 index ea7dce6..0000000 --- a/build.gradle +++ /dev/null @@ -1,166 +0,0 @@ -import net.fabricmc.loom.task.RemapJarTask - -plugins { - id 'com.github.johnrengelman.shadow' version '7.0.0' - id 'fabric-loom' version '1.0-SNAPSHOT' - id 'java' - id 'maven-publish' - id "com.modrinth.minotaur" version "2.+" -} - -sourceCompatibility = JavaVersion.VERSION_17 -targetCompatibility = JavaVersion.VERSION_17 - -archivesBaseName = project.archives_base_name -version = project.mod_version -group = project.maven_group - -loom { - accessWidenerPath = file("src/main/resources/floodgate.accesswidener") -} - -dependencies { - //to change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings loom.officialMojangMappings() - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - - // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - - // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. - // You may need to force-disable transitiveness on them. - - // Base Floodgate - implementation("org.geysermc.floodgate:core:${project.mod_version}") - shadow("org.geysermc.floodgate:core:${project.mod_version}") { - exclude group: "cloud.commandframework", module: "*" // Cloud is included jar-in-jar - exclude group: "org.geysermc.floodgate", module: "api" - exclude group: 'com.google.guava', module: "guava" - exclude group: 'com.google.code.gson', module: "gson" - exclude group: 'org.slf4j', module: "slf4j-api" - exclude group: 'it.unimi.dsi.fastutil', module: "*" - } - - shadow(implementation("org.geysermc.floodgate:api:${project.mod_version}")) { - exclude group: 'com.google.guava', module: "guava" - exclude group: 'com.google.code.gson', module: "gson" - exclude group: "org.ow2.asm", module: "*" // From Events lib - } - - include(modImplementation('cloud.commandframework:cloud-fabric:1.8.4') { - because "Commands library implementation for Fabric" - }) - - // Lombok - compileOnly "org.projectlombok:lombok:${project.lombok_version}" - annotationProcessor "org.projectlombok:lombok:${project.lombok_version}" -} - -repositories { - //mavenLocal() - maven { - url = 'https://oss.sonatype.org/content/repositories/snapshots' - } - // Standard OpenCollab repositories - maven { - name = 'opencollab-release-repo' - url = 'https://repo.opencollab.dev/maven-releases/' - //TODO set as releases - } - maven { - name = 'opencollab-snapshot-repo' - url = 'https://repo.opencollab.dev/maven-snapshots/' - } -} - -processResources { - inputs.property "version", project.version - - filesMatching("fabric.mod.json") { - expand "version": project.version - } -} - -// ensure that the encoding is set to UTF-8, no matter what the system default is -// this fixes some edge cases with special characters not displaying correctly -// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html -tasks.withType(JavaCompile) { - options.encoding = "UTF-8" -} - -java { - // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task - // if it is present. - // If you remove this line, sources will not be generated. - withSourcesJar() -} - -shadowJar { - configurations = [project.configurations.shadow] - // TODO this is temporary until Floodgate's dev branch is merged - relocate("com.google.inject", "org.geysermc.floodgate.shadow.guice") - relocate("org.yaml.snakeyaml", "org.geysermc.floodgate.shadow.snakeyaml") //relocate snakeyaml to avoid conflicts with other mods - exclude([ - 'cloud/**', - 'com/google/common/**', 'com/google/errorprone/**', 'com/google/gson/**', 'com/google/j2objc/**', 'com/google/thirdparty/**', - 'it/unimi/**', - 'org/slf4j/**' - ]) -} - -task remappedShadowJar(type: RemapJarTask) { - dependsOn tasks.shadowJar - input = tasks.shadowJar.archiveFile - addNestedDependencies = true - archiveName = "floodgate-fabric.jar" -} - -task remappedModrinthJar(type: RemapJarTask) { - dependsOn tasks.shadowJar - input = tasks.shadowJar.archiveFile - addNestedDependencies = true - version = "${project.mod_version}+build.${System.getenv("GITHUB_RUN_NUMBER")}" -} - -tasks.assemble.dependsOn tasks.remappedShadowJar - -artifacts { - archives remappedShadowJar - shadow shadowJar -} - -// configure the maven publication -publishing { - publications { - mavenJava(MavenPublication) { - from components.java - } - } - - // select the repositories you want to publish to - repositories { - mavenLocal() - } -} - -tasks.modrinth.dependsOn tasks.remappedModrinthJar - -modrinth { - token = System.getenv('MODRINTH_TOKEN') // Prevent GitHub Actions from caching empty Modrinth token - projectId = "bWrNNfkb" - versionNumber = project.version as String + "-" + System.getenv("GITHUB_RUN_NUMBER") - versionType = "beta" - changelog = "A changelog can be found at https://github.com/GeyserMC/Floodgate-Fabric/commits" - - syncBodyFrom = rootProject.file("README.md").text - - uploadFile = tasks.getByPath("remappedModrinthJar") - gameVersions.addAll("1.20.2", "1.20.4") - - loaders = ["fabric"] - - dependencies { - required.project "fabric-api" - } -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..5913d59 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,144 @@ +import net.fabricmc.loom.task.RemapJarTask + +plugins { + id("com.github.johnrengelman.shadow") version "8.1.1" + id("fabric-loom") version "1.6-SNAPSHOT" + id("java") + id("maven-publish") + id("com.modrinth.minotaur") version "2.+" +} + +loom { + accessWidenerPath = file("src/main/resources/floodgate.accesswidener") +} + +dependencies { + //to change the versions see the gradle.properties file + minecraft("com.mojang:minecraft:1.20.5") + mappings(loom.officialMojangMappings()) + modImplementation("net.fabricmc:fabric-loader:0.15.10") + + // Fabric API. This is technically optional, but you probably want it anyway. + modImplementation("net.fabricmc.fabric-api:fabric-api:0.97.6+1.20.5") + + // Base Floodgate + implementation("org.geysermc.floodgate:core:2.2.3-SNAPSHOT") + shadow("org.geysermc.floodgate:core:2.2.3-SNAPSHOT") { isTransitive = false } + shadow("org.geysermc.floodgate:api:2.2.3-SNAPSHOT") { isTransitive = false } + + // Requires relocation + shadow("org.bstats:bstats-base:3.0.2") + + // Shadow & relocate these since the (indirectly) depend on quite old dependencies + shadow("com.google.inject:guice:6.0.0") { isTransitive = false } + shadow("org.geysermc.configutils:configutils:1.0-SNAPSHOT") { + exclude("org.checkerframework") + exclude("com.google.errorprone") + exclude("com.github.spotbugs") + exclude("com.nukkitx.fastutil") + } + + include("aopalliance:aopalliance:1.0") + include("javax.inject:javax.inject:1") + include("jakarta.inject:jakarta.inject-api:2.0.1") + include("org.java-websocket:Java-WebSocket:1.5.2") + + // Just like Geyser, include these + include("org.geysermc.geyser", "common", "2.2.3-SNAPSHOT") + include("org.geysermc.cumulus", "cumulus", "1.1.2") + include("org.geysermc.event", "events", "1.1-SNAPSHOT") + include("org.lanternpowered", "lmbda", "2.0.0") // used in events + + // cloud + include("org.incendo:cloud-fabric:2.0.0-SNAPSHOT") + modImplementation("org.incendo:cloud-fabric:2.0.0-SNAPSHOT") + + // Lombok + compileOnly("org.projectlombok:lombok:1.18.32") + annotationProcessor("org.projectlombok:lombok:1.18.32") +} + +repositories { + //mavenLocal() + mavenCentral() + maven("https://maven.fabricmc.net/") + maven("https://repo.opencollab.dev/main/") + maven("https://jitpack.io") { + content { + includeGroupByRegex("com.github.*") + } + } + maven("https://oss.sonatype.org/content/repositories/snapshots/") + maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") +} + +java { + withSourcesJar() +} + +tasks { + shadowJar { + configurations = listOf(project.configurations.shadow.get()) + + relocate("org.bstats", "org.geysermc.floodgate.shadow.bstats") + relocate("com.google.inject", "org.geysermc.floodgate.shadow.google.inject") + relocate("org.yaml", "org.geysermc.floodgate.shadow.org.yaml") + } + + processResources { + filesMatching("fabric.mod.json") { + expand("version" to project.version) + } + } + + remapJar { + dependsOn(shadowJar) + mustRunAfter(shadowJar) + inputFile.set(shadowJar.get().archiveFile) + addNestedDependencies = true // todo? + archiveFileName.set("floodgate-fabric.jar") + } + + register("remapModrinthJar", RemapJarTask::class) { + dependsOn(shadowJar) + inputFile.set(remapJar.get().archiveFile) + addNestedDependencies = true + archiveVersion.set(project.version.toString() + "+build." + System.getenv("GITHUB_RUN_NUMBER")) + archiveClassifier.set("") + } +} + +publishing { + publications { + register("publish", MavenPublication::class) { + from(project.components["java"]) + + // skip shadow jar from publishing. Workaround for https://github.com/johnrengelman/shadow/issues/651 + val javaComponent = project.components["java"] as AdhocComponentWithVariants + javaComponent.withVariantsFromConfiguration(configurations["shadowRuntimeElements"]) { skip() } + } + } + + repositories { + mavenLocal() + } +} + +modrinth { + token.set(System.getenv("MODRINTH_TOKEN")) // Prevent GitHub Actions from caching empty Modrinth token + projectId.set("bWrNNfkb") + versionNumber.set(project.version as String + "-" + System.getenv("GITHUB_RUN_NUMBER")) + versionType.set("beta") + changelog.set("A changelog can be found at https://github.com/GeyserMC/Floodgate-Fabric/commits") + + syncBodyFrom.set(rootProject.file("README.md").readText()) + + uploadFile.set(tasks.named("remapModrinthJar")) + gameVersions.addAll("1.20.5") + + loaders.add("fabric") + + dependencies { + required.project("fabric-api") + } +} diff --git a/gradle.properties b/gradle.properties index 1d56e9a..573a53c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,15 +1,6 @@ # Done to increase the memory available to gradle. org.gradle.jvmargs=-Xmx2G -# Fabric Properties -# check these on https://modmuss50.me/fabric.html -minecraft_version=1.20.4 -loader_version=0.15.2 # Mod Properties -mod_version=2.2.0-SNAPSHOT -maven_group=org.geysermc.floodgate +version=2.2.3-SNAPSHOT +group=org.geysermc.floodgate archives_base_name=floodgate-fabric -# Dependencies -# check this on https://modmuss50.me/fabric.html -fabric_version=0.91.2+1.20.4 -# Our stuff -lombok_version=1.18.20 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e750102..48c0a02 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 1b6c787..c53aefa 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -32,10 +32,10 @@ # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: # * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». # # Important for patching: # diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 5b60df3..0000000 --- a/settings.gradle +++ /dev/null @@ -1,10 +0,0 @@ -pluginManagement { - repositories { - jcenter() - maven { - name = 'Fabric' - url = 'https://maven.fabricmc.net/' - } - gradlePluginPortal() - } -} diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..71ef923 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,8 @@ +pluginManagement { + repositories { + //mavenLocal() + mavenCentral() + gradlePluginPortal() + maven("https://maven.fabricmc.net/") + } +} diff --git a/src/main/java/org/geysermc/floodgate/FabricMod.java b/src/main/java/org/geysermc/floodgate/FabricMod.java index 1eaab88..a2da132 100644 --- a/src/main/java/org/geysermc/floodgate/FabricMod.java +++ b/src/main/java/org/geysermc/floodgate/FabricMod.java @@ -19,7 +19,7 @@ public void onInitialize() { new FabricPlatformModule() ); - FabricPlatform platform = injector.getInstance(FabricPlatform.class); + FloodgatePlatform platform = injector.getInstance(FloodgatePlatform.class); platform.enable(new FabricCommandModule()); diff --git a/src/main/java/org/geysermc/floodgate/FabricPlatform.java b/src/main/java/org/geysermc/floodgate/FabricPlatform.java deleted file mode 100644 index af1a0a2..0000000 --- a/src/main/java/org/geysermc/floodgate/FabricPlatform.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.geysermc.floodgate; - -import com.google.inject.Inject; -import com.google.inject.Injector; -import org.geysermc.floodgate.api.FloodgateApi; -import org.geysermc.floodgate.api.inject.PlatformInjector; -import org.geysermc.floodgate.api.logger.FloodgateLogger; - -public final class FabricPlatform extends FloodgatePlatform { - @Inject - public FabricPlatform(FloodgateApi api, PlatformInjector platformInjector, FloodgateLogger logger, Injector guice) { - super(api, platformInjector, logger, guice); - } -} diff --git a/src/main/java/org/geysermc/floodgate/inject/fabric/FabricInjector.java b/src/main/java/org/geysermc/floodgate/inject/fabric/FabricInjector.java index bbba015..e5a767f 100644 --- a/src/main/java/org/geysermc/floodgate/inject/fabric/FabricInjector.java +++ b/src/main/java/org/geysermc/floodgate/inject/fabric/FabricInjector.java @@ -3,6 +3,7 @@ import io.netty.channel.*; import lombok.Getter; import lombok.RequiredArgsConstructor; +import org.checkerframework.checker.nullness.qual.NonNull; import org.geysermc.floodgate.inject.CommonPlatformInjector; @RequiredArgsConstructor @@ -12,23 +13,23 @@ public final class FabricInjector extends CommonPlatformInjector { @Getter private final boolean injected = true; @Override - public boolean inject() throws Exception { - return true; + public void inject() throws Exception { + //no-op } public void injectClient(ChannelFuture future) { future.channel().pipeline().addFirst("floodgate-init", new ChannelInboundHandlerAdapter() { @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + public void channelRead(@NonNull ChannelHandlerContext ctx, @NonNull Object msg) throws Exception { super.channelRead(ctx, msg); if (!(msg instanceof Channel channel)) { return; } - channel.pipeline().addLast(new ChannelInitializer() { + channel.pipeline().addLast(new ChannelInitializer<>() { @Override - protected void initChannel(Channel channel) { + protected void initChannel(@NonNull Channel channel) { injectAddonsCall(channel, false); addInjectedClient(channel); channel.closeFuture().addListener(listener -> { @@ -42,8 +43,8 @@ protected void initChannel(Channel channel) { } @Override - public boolean removeInjection() throws Exception { - return true; + public void removeInjection() throws Exception { + //no-op } public static FabricInjector getInstance() { diff --git a/src/main/java/org/geysermc/floodgate/logger/Log4jFloodgateLogger.java b/src/main/java/org/geysermc/floodgate/logger/Log4jFloodgateLogger.java index a4cb38f..d24223f 100644 --- a/src/main/java/org/geysermc/floodgate/logger/Log4jFloodgateLogger.java +++ b/src/main/java/org/geysermc/floodgate/logger/Log4jFloodgateLogger.java @@ -1,18 +1,31 @@ package org.geysermc.floodgate.logger; -import lombok.RequiredArgsConstructor; +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.config.FloodgateConfig; import org.geysermc.floodgate.util.LanguageManager; import static org.geysermc.floodgate.util.MessageFormatter.format; -@RequiredArgsConstructor +@Singleton public final class Log4jFloodgateLogger implements FloodgateLogger { - private final Logger logger; - private final LanguageManager languageManager; + @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) { @@ -49,20 +62,6 @@ public void trace(String message, Object... args) { logger.trace(message, args); } - @Override - public void enableDebug() { - if (!logger.isDebugEnabled()) { - Configurator.setLevel(logger.getName(), Level.DEBUG); - } - } - - @Override - public void disableDebug() { - if (logger.isDebugEnabled()) { - Configurator.setLevel(logger.getName(), Level.INFO); - } - } - @Override public boolean isDebug() { return logger.isDebugEnabled(); diff --git a/src/main/java/org/geysermc/floodgate/module/FabricCommandModule.java b/src/main/java/org/geysermc/floodgate/module/FabricCommandModule.java index c673027..c02adb1 100644 --- a/src/main/java/org/geysermc/floodgate/module/FabricCommandModule.java +++ b/src/main/java/org/geysermc/floodgate/module/FabricCommandModule.java @@ -1,9 +1,5 @@ package org.geysermc.floodgate.module; -import cloud.commandframework.CommandManager; -import cloud.commandframework.execution.CommandExecutionCoordinator; -import cloud.commandframework.fabric.FabricCommandManager; -import cloud.commandframework.fabric.FabricServerCommandManager; import com.google.inject.Provides; import com.google.inject.Singleton; import lombok.SneakyThrows; @@ -11,6 +7,11 @@ import org.geysermc.floodgate.platform.command.CommandUtil; import org.geysermc.floodgate.player.FloodgateCommandPreprocessor; import org.geysermc.floodgate.player.UserAudience; +import org.geysermc.floodgate.player.audience.FloodgateSenderMapper; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.execution.ExecutionCoordinator; +import org.incendo.cloud.fabric.FabricCommandManager; +import org.incendo.cloud.fabric.FabricServerCommandManager; public final class FabricCommandModule extends CommandModule { @Provides @@ -18,9 +19,8 @@ public final class FabricCommandModule extends CommandModule { @SneakyThrows public CommandManager commandManager(CommandUtil commandUtil) { FabricCommandManager commandManager = new FabricServerCommandManager<>( - CommandExecutionCoordinator.simpleCoordinator(), - commandUtil::getUserAudience, - audience -> (CommandSourceStack) audience.source() + ExecutionCoordinator.simpleCoordinator(), + new FloodgateSenderMapper<>(commandUtil) ); commandManager.registerCommandPreProcessor(new FloodgateCommandPreprocessor<>(commandUtil)); return commandManager; diff --git a/src/main/java/org/geysermc/floodgate/module/FabricPlatformModule.java b/src/main/java/org/geysermc/floodgate/module/FabricPlatformModule.java index 3071107..9a59283 100644 --- a/src/main/java/org/geysermc/floodgate/module/FabricPlatformModule.java +++ b/src/main/java/org/geysermc/floodgate/module/FabricPlatformModule.java @@ -1,5 +1,7 @@ package org.geysermc.floodgate.module; +import com.google.inject.name.Names; +import org.apache.logging.log4j.Logger; import org.geysermc.floodgate.inject.fabric.FabricInjector; import org.geysermc.floodgate.listener.FabricEventListener; import org.geysermc.floodgate.listener.FabricEventRegistration; @@ -32,12 +34,8 @@ public final class FabricPlatformModule extends AbstractModule { @Override protected void configure() { bind(PlatformUtils.class).to(FabricPlatformUtils.class); - } - - @Provides - @Singleton - public FloodgateLogger floodgateLogger(LanguageManager languageManager) { - return new Log4jFloodgateLogger(LogManager.getLogger("floodgate"), languageManager); + bind(Logger.class).annotatedWith(Names.named("logger")).toInstance(LogManager.getLogger("floodgate")); + bind(FloodgateLogger.class).to(Log4jFloodgateLogger.class); } @Provides diff --git a/src/main/java/org/geysermc/floodgate/pluginmessage/FabricPluginMessageRegistration.java b/src/main/java/org/geysermc/floodgate/pluginmessage/FabricPluginMessageRegistration.java index 09ab54c..ee5b781 100644 --- a/src/main/java/org/geysermc/floodgate/pluginmessage/FabricPluginMessageRegistration.java +++ b/src/main/java/org/geysermc/floodgate/pluginmessage/FabricPluginMessageRegistration.java @@ -1,16 +1,53 @@ package org.geysermc.floodgate.pluginmessage; +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; -import net.minecraft.resources.ResourceLocation; +import org.geysermc.floodgate.pluginmessage.payloads.FormPayload; +import org.geysermc.floodgate.pluginmessage.payloads.PacketPayload; +import org.geysermc.floodgate.pluginmessage.payloads.SkinPayload; +import org.geysermc.floodgate.pluginmessage.payloads.TransferPayload; public class FabricPluginMessageRegistration implements PluginMessageRegistration { @Override public void register(PluginMessageChannel channel) { - ServerPlayNetworking.registerGlobalReceiver(new ResourceLocation(channel.getIdentifier()), - (server, player, handler, buf, responseSender) -> { - byte[] bytes = new byte[buf.readableBytes()]; - buf.readBytes(bytes); - channel.handleServerCall(bytes, player.getUUID(), player.getGameProfile().getName()); - }); + 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); + } } } diff --git a/src/main/java/org/geysermc/floodgate/pluginmessage/FabricPluginMessageUtils.java b/src/main/java/org/geysermc/floodgate/pluginmessage/FabricPluginMessageUtils.java index 63b597a..6a5b3b4 100644 --- a/src/main/java/org/geysermc/floodgate/pluginmessage/FabricPluginMessageUtils.java +++ b/src/main/java/org/geysermc/floodgate/pluginmessage/FabricPluginMessageUtils.java @@ -1,13 +1,23 @@ package org.geysermc.floodgate.pluginmessage; import io.netty.buffer.Unpooled; +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import org.geysermc.floodgate.MinecraftServerHolder; +import org.geysermc.floodgate.api.FloodgateApi; +import org.geysermc.floodgate.api.InstanceHolder; import org.geysermc.floodgate.platform.pluginmessage.PluginMessageUtils; +import org.geysermc.floodgate.pluginmessage.payloads.FormPayload; +import org.geysermc.floodgate.pluginmessage.payloads.PacketPayload; +import org.geysermc.floodgate.pluginmessage.payloads.SkinPayload; +import org.geysermc.floodgate.pluginmessage.payloads.TransferPayload; +import java.util.Objects; import java.util.UUID; public class FabricPluginMessageUtils extends PluginMessageUtils { @@ -16,9 +26,17 @@ public class FabricPluginMessageUtils extends PluginMessageUtils { public boolean sendMessage(UUID uuid, String channel, byte[] data) { try { ServerPlayer player = MinecraftServerHolder.get().getPlayerList().getPlayer(uuid); - ResourceLocation resource = new ResourceLocation(channel); // automatically splits over the : - FriendlyByteBuf dataBuffer = new FriendlyByteBuf(Unpooled.wrappedBuffer(data)); - ServerPlayNetworking.send(player, resource, dataBuffer); + final CustomPacketPayload payload; + switch (channel) { + case "floodgate:form" -> payload = new FormPayload(data); + case "floodgate:packet" -> payload = new PacketPayload(data); + case "floodgate:skin" -> payload = new SkinPayload(data); + case "floodgate:transfer" -> payload = new TransferPayload(data); + default -> throw new IllegalArgumentException("unknown channel: " + channel); + } + + Objects.requireNonNull(player); + ServerPlayNetworking.send(player, payload); } catch (Exception e) { e.printStackTrace(); return false; diff --git a/src/main/java/org/geysermc/floodgate/pluginmessage/FabricSkinApplier.java b/src/main/java/org/geysermc/floodgate/pluginmessage/FabricSkinApplier.java index 7d5107e..374c2d8 100644 --- a/src/main/java/org/geysermc/floodgate/pluginmessage/FabricSkinApplier.java +++ b/src/main/java/org/geysermc/floodgate/pluginmessage/FabricSkinApplier.java @@ -7,18 +7,20 @@ 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.MinecraftServerHolder; import org.geysermc.floodgate.api.player.FloodgatePlayer; import org.geysermc.floodgate.mixin.ChunkMapMixin; import org.geysermc.floodgate.skin.SkinApplier; -import org.geysermc.floodgate.skin.SkinData; + +import static org.geysermc.floodgate.api.event.skin.SkinApplyEvent.SkinData; import java.util.Collections; public final class FabricSkinApplier implements SkinApplier { @Override - public void applySkin(FloodgatePlayer floodgatePlayer, SkinData skinData) { + public void applySkin(@NonNull FloodgatePlayer floodgatePlayer, @NonNull SkinData skinData) { MinecraftServerHolder.get().execute(() -> { ServerPlayer bedrockPlayer = MinecraftServerHolder.get().getPlayerList() .getPlayer(floodgatePlayer.getCorrectUniqueId()); @@ -31,7 +33,7 @@ public void applySkin(FloodgatePlayer floodgatePlayer, SkinData skinData) { PropertyMap properties = bedrockPlayer.getGameProfile().getProperties(); properties.removeAll("textures"); - properties.put("textures", new Property("textures", skinData.getValue(), skinData.getSignature())); + properties.put("textures", new Property("textures", skinData.value(), skinData.signature())); ChunkMap tracker = ((ServerLevel) bedrockPlayer.level).getChunkSource().chunkMap; ChunkMap.TrackedEntity entry = ((ChunkMapMixin) tracker).getEntityMap().get(bedrockPlayer.getId()); diff --git a/src/main/java/org/geysermc/floodgate/pluginmessage/payloads/FormPayload.java b/src/main/java/org/geysermc/floodgate/pluginmessage/payloads/FormPayload.java new file mode 100644 index 0000000..132e39b --- /dev/null +++ b/src/main/java/org/geysermc/floodgate/pluginmessage/payloads/FormPayload.java @@ -0,0 +1,27 @@ +package org.geysermc.floodgate.pluginmessage.payloads; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import org.checkerframework.checker.nullness.qual.NonNull; + +public record FormPayload(byte[] data) implements CustomPacketPayload { + public static final StreamCodec STREAM_CODEC = CustomPacketPayload.codec(FormPayload::write, FormPayload::new); + public static final CustomPacketPayload.Type TYPE = CustomPacketPayload.createType("floodgate:form"); + + private FormPayload(FriendlyByteBuf friendlyByteBuf) { + this(friendlyByteBuf.readByteArray()); + } + + private void write(FriendlyByteBuf friendlyByteBuf) { + friendlyByteBuf.writeByteArray(this.data); + } + + public CustomPacketPayload.@NonNull Type type() { + return TYPE; + } + + public byte[] data() { + return this.data; + } +} \ No newline at end of file diff --git a/src/main/java/org/geysermc/floodgate/pluginmessage/payloads/PacketPayload.java b/src/main/java/org/geysermc/floodgate/pluginmessage/payloads/PacketPayload.java new file mode 100644 index 0000000..89276b5 --- /dev/null +++ b/src/main/java/org/geysermc/floodgate/pluginmessage/payloads/PacketPayload.java @@ -0,0 +1,27 @@ +package org.geysermc.floodgate.pluginmessage.payloads; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import org.checkerframework.checker.nullness.qual.NonNull; + +public record PacketPayload(byte[] data) implements CustomPacketPayload { + public static final StreamCodec STREAM_CODEC = CustomPacketPayload.codec(PacketPayload::write, PacketPayload::new); + public static final CustomPacketPayload.Type TYPE = CustomPacketPayload.createType("floodgate:packet"); + + private PacketPayload(FriendlyByteBuf friendlyByteBuf) { + this(friendlyByteBuf.readByteArray()); + } + + private void write(FriendlyByteBuf friendlyByteBuf) { + friendlyByteBuf.writeByteArray(this.data); + } + + public CustomPacketPayload.@NonNull Type type() { + return TYPE; + } + + public byte[] data() { + return this.data; + } +} \ No newline at end of file diff --git a/src/main/java/org/geysermc/floodgate/pluginmessage/payloads/SkinPayload.java b/src/main/java/org/geysermc/floodgate/pluginmessage/payloads/SkinPayload.java new file mode 100644 index 0000000..a2507e5 --- /dev/null +++ b/src/main/java/org/geysermc/floodgate/pluginmessage/payloads/SkinPayload.java @@ -0,0 +1,27 @@ +package org.geysermc.floodgate.pluginmessage.payloads; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import org.checkerframework.checker.nullness.qual.NonNull; + +public record SkinPayload(byte[] data) implements CustomPacketPayload { + public static final StreamCodec STREAM_CODEC = CustomPacketPayload.codec(SkinPayload::write, SkinPayload::new); + public static final CustomPacketPayload.Type TYPE = CustomPacketPayload.createType("floodgate:skin"); + + private SkinPayload(FriendlyByteBuf friendlyByteBuf) { + this(friendlyByteBuf.readByteArray()); + } + + private void write(FriendlyByteBuf friendlyByteBuf) { + friendlyByteBuf.writeByteArray(this.data); + } + + public CustomPacketPayload.@NonNull Type type() { + return TYPE; + } + + public byte[] data() { + return this.data; + } +} \ No newline at end of file diff --git a/src/main/java/org/geysermc/floodgate/pluginmessage/payloads/TransferPayload.java b/src/main/java/org/geysermc/floodgate/pluginmessage/payloads/TransferPayload.java new file mode 100644 index 0000000..b291b92 --- /dev/null +++ b/src/main/java/org/geysermc/floodgate/pluginmessage/payloads/TransferPayload.java @@ -0,0 +1,27 @@ +package org.geysermc.floodgate.pluginmessage.payloads; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import org.checkerframework.checker.nullness.qual.NonNull; + +public record TransferPayload(byte[] data) implements CustomPacketPayload { + public static final StreamCodec STREAM_CODEC = CustomPacketPayload.codec(TransferPayload::write, TransferPayload::new); + public static final CustomPacketPayload.Type TYPE = CustomPacketPayload.createType("floodgate:transfer"); + + private TransferPayload(FriendlyByteBuf friendlyByteBuf) { + this(friendlyByteBuf.readByteArray()); + } + + private void write(FriendlyByteBuf friendlyByteBuf) { + friendlyByteBuf.writeByteArray(this.data); + } + + public CustomPacketPayload.@NonNull Type type() { + return TYPE; + } + + public byte[] data() { + return this.data; + } +} \ No newline at end of file diff --git a/src/main/java/org/geysermc/floodgate/util/FabricCommandUtil.java b/src/main/java/org/geysermc/floodgate/util/FabricCommandUtil.java index 3176f50..0382148 100644 --- a/src/main/java/org/geysermc/floodgate/util/FabricCommandUtil.java +++ b/src/main/java/org/geysermc/floodgate/util/FabricCommandUtil.java @@ -2,6 +2,7 @@ import com.mojang.authlib.GameProfile; import me.lucko.fabric.api.permissions.v0.Permissions; +import net.minecraft.commands.CommandSource; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.network.chat.Component; @@ -15,6 +16,7 @@ import org.geysermc.floodgate.player.UserAudience; import java.util.*; +import java.util.logging.Logger; public final class FabricCommandUtil extends CommandUtil { private final FloodgateLogger logger; @@ -26,7 +28,7 @@ public FabricCommandUtil(LanguageManager manager, FloodgateApi api, FloodgateLog } @Override - public UserAudience getUserAudience(final @NonNull Object sourceObj) { + public @NonNull UserAudience getUserAudience(final @NonNull Object sourceObj) { if (!(sourceObj instanceof CommandSourceStack stack)) { throw new IllegalArgumentException(); } @@ -71,7 +73,8 @@ protected Collection getOnlinePlayers() { @Override public boolean hasPermission(Object source, String permission) { - return Permissions.check((SharedSuggestionProvider) source, permission); + return Permissions.check((SharedSuggestionProvider) source, + permission, MinecraftServerHolder.get().getOperatorUserPermissionLevel()); } @Override diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index a80208d..bdca63a 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -24,8 +24,8 @@ "floodgate.mixins.json" ], "depends": { - "fabricloader": ">=0.14.22", + "fabricloader": ">=0.15.10", "fabric": "*", - "minecraft": ">=1.20.2" + "minecraft": ">=1.20.5" } } \ No newline at end of file