mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2025-12-19 14:59:20 +00:00
Support neoforge platform, move to using architectury (#125)
* rebase * split fabric/neoforge specific code * more progress * dependency configuration * exclude more junk * neo, you make me go insane * neoforge seems to work! * some minor cleanup, add neoforge command module * mixin config plugin shenanigans * fix language strings loading * some cleanup, yeet Jenkinsfile * proper repository declaration using plugin, target jitpack branch * oops * address reviews * Update for 1.21 * some minor fixes * Fix modrinth task, add floodgate version command mixin to disable version checking, update to loom 1.7, update cloud, update floodgate core to not use my branch * oops * what on earth is going on now * neoforge works again!!!!!!!!! * Address review, dont rely on locals in mixin * modrinth version/name changes, similar to geyser * Update README.md Co-authored-by: Konicai <71294714+Konicai@users.noreply.github.com> * Improve handling of PayloadRegistrar this took years off my life * address review * Move blossom version declaration to libs.versions.toml * remove unused versions from catalogue * Only run modrinth task if successful & on Geyser repo * cleanup & fix gh actions building/archiving * run and uses are different steps --------- Co-authored-by: Konicai <71294714+Konicai@users.noreply.github.com>
This commit is contained in:
22
.github/workflows/publish.yml
vendored
22
.github/workflows/publish.yml
vendored
@@ -5,23 +5,27 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@72f2cec99f417b1a1c5e2e88945068983b7965f9
|
||||
- uses: gradle/wrapper-validation-action@56b90f209b02bf6d1deae490e9ef18b21a389cd4
|
||||
- uses: actions/setup-java@4075bfc1b51bf22876335ae1cd589602d60d8758
|
||||
- name: Setup Gradle
|
||||
uses: GeyserMC/actions/setup-gradle-composite@master
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
setup-java_java-version: 21
|
||||
|
||||
- name: Build Floodgate-Modded
|
||||
run: ./gradlew build
|
||||
|
||||
- name: Publish to Modrinth
|
||||
if: ${{ success() && github.repository == 'GeyserMC/Floodgate-Modded' && github.ref_name == 'master' }}
|
||||
uses: gradle/gradle-build-action@3bfe3a46584a206fb8361cdedd0647b0c4204232
|
||||
env:
|
||||
MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
|
||||
with:
|
||||
arguments: modrinth
|
||||
gradle-home-cache-cleanup: true
|
||||
|
||||
- name: Archive Artifacts
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32
|
||||
uses: GeyserMC/actions/upload-multi-artifact@master
|
||||
if: success()
|
||||
with:
|
||||
name: Floodgate Fabric
|
||||
path: build/libs/floodgate-fabric.jar
|
||||
if-no-files-found: error
|
||||
artifacts: |
|
||||
Floodgate-Fabric:fabric/build/libs/floodgate-fabric.jar
|
||||
Floodgate-NeoForge:neoforge/build/libs/floodgate-neoforge.jar
|
||||
|
||||
13
README.md
13
README.md
@@ -1,4 +1,11 @@
|
||||
# Floodgate-Fabric
|
||||
Fabric port of the hybrid mode plugin to allow for connections from Geyser to join online mode servers.
|
||||
# Floodgate-Modded
|
||||
Fabric and NeoForge ports of the hybrid mode plugin to allow for connections from Geyser to join online mode servers.
|
||||
|
||||
Download: https://ci.opencollab.dev/job/GeyserMC/job/Floodgate-Fabric/job/master/
|
||||
Hybrid mode mod to allow for connections from Geyser to join online mode servers.
|
||||
Geyser is an open collaboration project by CubeCraft Games.
|
||||
|
||||
See the Floodgate section in the GeyserMC Wiki for more info about what Floodgate is, how you setup Floodgate and known issues/caveats.
|
||||
Additionally, it includes a more in-depth look into how Floodgate works and the Floodgate API.
|
||||
|
||||
Wiki: https://wiki.geysermc.org/floodgate/
|
||||
Download: https://modrinth.com/mod/floodgate
|
||||
|
||||
23
build-logic/build.gradle.kts
Normal file
23
build-logic/build.gradle.kts
Normal file
@@ -0,0 +1,23 @@
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
mavenCentral()
|
||||
maven("https://maven.architectury.dev/")
|
||||
maven("https://maven.fabricmc.net/")
|
||||
maven("https://maven.neoforged.net/releases/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Used to access version catalogue from the convention plugins
|
||||
// this is OK as long as the same version catalog is used in the main build and build-logic
|
||||
// see https://github.com/gradle/gradle/issues/15383#issuecomment-779893192
|
||||
implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
|
||||
implementation(libs.indra)
|
||||
implementation(libs.shadow)
|
||||
implementation(libs.architectury.plugin)
|
||||
implementation(libs.architectury.loom)
|
||||
implementation(libs.minotaur)
|
||||
}
|
||||
11
build-logic/settings.gradle.kts
Normal file
11
build-logic/settings.gradle.kts
Normal file
@@ -0,0 +1,11 @@
|
||||
@file:Suppress("UnstableApiUsage")
|
||||
|
||||
dependencyResolutionManagement {
|
||||
versionCatalogs {
|
||||
create("libs") {
|
||||
from(files("../gradle/libs.versions.toml"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "build-logic"
|
||||
6
build-logic/src/main/kotlin/LibsAccessor.kt
Normal file
6
build-logic/src/main/kotlin/LibsAccessor.kt
Normal file
@@ -0,0 +1,6 @@
|
||||
import org.gradle.accessors.dm.LibrariesForLibs
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
|
||||
val Project.libs: LibrariesForLibs
|
||||
get() = rootProject.extensions.getByType()
|
||||
36
build-logic/src/main/kotlin/extensions.kt
Normal file
36
build-logic/src/main/kotlin/extensions.kt
Normal file
@@ -0,0 +1,36 @@
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.MinimalExternalModuleDependency
|
||||
import org.gradle.api.artifacts.ProjectDependency
|
||||
import org.gradle.api.provider.Provider
|
||||
|
||||
val providedDependencies = mutableMapOf<String, MutableSet<String>>()
|
||||
|
||||
fun Project.provided(pattern: String, name: String, excludedOn: Int = 0b110) {
|
||||
providedDependencies.getOrPut(project.name) { mutableSetOf() }
|
||||
.add("${calcExclusion(pattern, 0b100, excludedOn)}:${calcExclusion(name, 0b10, excludedOn)}")
|
||||
}
|
||||
|
||||
fun Project.provided(dependency: ProjectDependency) =
|
||||
provided(dependency.group!!, dependency.name)
|
||||
|
||||
fun Project.provided(dependency: MinimalExternalModuleDependency) =
|
||||
provided(dependency.module.group, dependency.module.name)
|
||||
|
||||
fun Project.provided(provider: Provider<MinimalExternalModuleDependency>) =
|
||||
provided(provider.get())
|
||||
|
||||
fun getProvidedDependenciesForProject(projectName: String): MutableSet<String> {
|
||||
return providedDependencies.getOrDefault(projectName, emptySet()).toMutableSet()
|
||||
}
|
||||
|
||||
private fun calcExclusion(section: String, bit: Int, excludedOn: Int): String =
|
||||
if (excludedOn and bit > 0) section else ""
|
||||
|
||||
fun projectVersion(project: Project): String =
|
||||
project.version.toString().replace("SNAPSHOT", "b" + buildNumber())
|
||||
|
||||
fun versionName(project: Project): String =
|
||||
"Floodgate-" + project.name.replaceFirstChar { it.uppercase() } + "-" + projectVersion(project)
|
||||
|
||||
fun buildNumber(): Int =
|
||||
(System.getenv("GITHUB_RUN_NUMBER"))?.let { Integer.parseInt(it) } ?: -1
|
||||
@@ -0,0 +1,37 @@
|
||||
plugins {
|
||||
`java-library`
|
||||
id("net.kyori.indra")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("org.checkerframework", "checker-qual", "3.19.0")
|
||||
}
|
||||
|
||||
indra {
|
||||
github("GeyserMC", "floodgate-modded") {
|
||||
ci(true)
|
||||
issues(true)
|
||||
scm(true)
|
||||
}
|
||||
mitLicense()
|
||||
|
||||
javaVersions {
|
||||
target(21)
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
processResources {
|
||||
filesMatching(listOf("fabric.mod.json", "META-INF/neoforge.mods.toml")) {
|
||||
expand(
|
||||
"id" to "floodgate",
|
||||
"name" to "Floodgate",
|
||||
"version" to project.version,
|
||||
"description" to project.description,
|
||||
"url" to "https://geysermc.org",
|
||||
"author" to "GeyserMC",
|
||||
"minecraft_version" to libs.versions.minecraft.version.get()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
repositories {
|
||||
// mavenLocal()
|
||||
mavenCentral()
|
||||
maven("https://maven.fabricmc.net/")
|
||||
maven("https://maven.neoforged.net/releases")
|
||||
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/")
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
import net.fabricmc.loom.task.RemapJarTask
|
||||
|
||||
plugins {
|
||||
id("floodgate-modded.publish-conventions")
|
||||
id("architectury-plugin")
|
||||
id("dev.architectury.loom")
|
||||
id("com.modrinth.minotaur")
|
||||
}
|
||||
|
||||
// These are all provided by Minecraft/server platforms
|
||||
provided("com.google.code.gson", "gson")
|
||||
provided("org.slf4j", ".*")
|
||||
provided("com.google.guava", "guava")
|
||||
provided("org.ow2.asm", "asm")
|
||||
provided("com.nukkitx.fastutil", ".*")
|
||||
|
||||
// these we just don't want to include
|
||||
provided("org.checkerframework", ".*")
|
||||
provided("com.google.errorprone", ".*")
|
||||
provided("com.github.spotbugs", "spotbugs-annotations")
|
||||
provided("com.google.code.findbugs", ".*")
|
||||
|
||||
// cloud-fabric/cloud-neoforge jij's all cloud depends already
|
||||
provided("org.incendo", ".*")
|
||||
provided("io.leangen.geantyref", "geantyref")
|
||||
|
||||
architectury {
|
||||
minecraft = libs.versions.minecraft.version.get()
|
||||
}
|
||||
|
||||
loom {
|
||||
silentMojangMappingsLicense()
|
||||
}
|
||||
|
||||
configurations {
|
||||
create("includeTransitive").isTransitive = true
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft(libs.minecraft)
|
||||
mappings(loom.officialMojangMappings())
|
||||
|
||||
// These are under our own namespace
|
||||
shadow(libs.floodgate.api) { isTransitive = false }
|
||||
shadow(libs.floodgate.core) { isTransitive = false }
|
||||
|
||||
// Requires relocation
|
||||
shadow(libs.bstats) { isTransitive = false }
|
||||
|
||||
// Shadow & relocate these since the (indirectly) depend on quite old dependencies
|
||||
shadow(libs.guice) { isTransitive = false }
|
||||
shadow(libs.configutils) {
|
||||
exclude("org.checkerframework")
|
||||
exclude("com.google.errorprone")
|
||||
exclude("com.github.spotbugs")
|
||||
exclude("com.nukkitx.fastutil")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
tasks {
|
||||
sourcesJar {
|
||||
archiveClassifier.set("sources")
|
||||
from(sourceSets.main.get().allSource)
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
// Mirrors the example fabric project, otherwise tons of dependencies are shaded that shouldn't be
|
||||
configurations = listOf(project.configurations.shadow.get())
|
||||
|
||||
// Relocate these
|
||||
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")
|
||||
|
||||
// The remapped shadowJar is the final desired mod jar
|
||||
archiveVersion.set(project.version.toString())
|
||||
archiveClassifier.set("shaded")
|
||||
}
|
||||
|
||||
remapJar {
|
||||
dependsOn(shadowJar)
|
||||
inputFile.set(shadowJar.get().archiveFile)
|
||||
archiveClassifier.set("")
|
||||
archiveVersion.set("")
|
||||
}
|
||||
|
||||
register("remapModrinthJar", RemapJarTask::class) {
|
||||
dependsOn(shadowJar)
|
||||
inputFile.set(shadowJar.get().archiveFile)
|
||||
archiveVersion.set(versionName(project))
|
||||
archiveClassifier.set("")
|
||||
}
|
||||
|
||||
// Readme sync
|
||||
modrinth.get().dependsOn(tasks.modrinthSyncBody)
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
val providedDependencies = getProvidedDependenciesForProject(project.name)
|
||||
|
||||
// These are shaded, no need to JiJ them
|
||||
configurations["shadow"].resolvedConfiguration.resolvedArtifacts.forEach {shadowed ->
|
||||
val string = "${shadowed.moduleVersion.id.group}:${shadowed.moduleVersion.id.name}"
|
||||
println("Not including shadowed dependency: $string")
|
||||
providedDependencies.add(string)
|
||||
}
|
||||
|
||||
configurations["includeTransitive"].resolvedConfiguration.resolvedArtifacts.forEach { dep ->
|
||||
if (!providedDependencies.contains("${dep.moduleVersion.id.group}:${dep.moduleVersion.id.name}")
|
||||
and !providedDependencies.contains("${dep.moduleVersion.id.group}:.*")) {
|
||||
println("Including dependency via JiJ: ${dep.id}")
|
||||
dependencies.add("include", dep.moduleVersion.id.toString())
|
||||
} else {
|
||||
println("Not including ${dep.id} for ${project.name}!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
modrinth {
|
||||
token.set(System.getenv("MODRINTH_TOKEN")) // Even though this is the default value, apparently this prevents GitHub Actions caching the token?
|
||||
projectId.set("bWrNNfkb")
|
||||
versionName.set(versionName(project))
|
||||
versionNumber.set(projectVersion(project))
|
||||
versionType.set("release")
|
||||
changelog.set("A changelog can be found at https://github.com/GeyserMC/Floodgate-Modded/commits")
|
||||
|
||||
syncBodyFrom.set(rootProject.file("README.md").readText())
|
||||
|
||||
uploadFile.set(tasks.getByPath("remapModrinthJar"))
|
||||
gameVersions.add(libs.minecraft.get().version as String)
|
||||
gameVersions.add("1.21.1")
|
||||
failSilently.set(false)
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
plugins {
|
||||
id("floodgate-modded.shadow-conventions")
|
||||
id("net.kyori.indra.publishing")
|
||||
}
|
||||
|
||||
indra {
|
||||
publishSnapshotsTo("geysermc", "https://repo.opencollab.dev/maven-snapshots")
|
||||
publishReleasesTo("geysermc", "https://repo.opencollab.dev/maven-releases")
|
||||
}
|
||||
|
||||
publishing {
|
||||
// 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() }
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
|
||||
plugins {
|
||||
id("floodgate-modded.base-conventions")
|
||||
id("com.github.johnrengelman.shadow")
|
||||
}
|
||||
|
||||
tasks {
|
||||
named<Jar>("jar") {
|
||||
archiveClassifier.set("unshaded")
|
||||
from(project.rootProject.file("LICENSE"))
|
||||
}
|
||||
val shadowJar = named<ShadowJar>("shadowJar") {
|
||||
archiveBaseName.set(project.name)
|
||||
archiveVersion.set("")
|
||||
archiveClassifier.set("")
|
||||
|
||||
val sJar: ShadowJar = this
|
||||
|
||||
doFirst {
|
||||
providedDependencies[project.name]?.forEach { string ->
|
||||
sJar.dependencies {
|
||||
println("Excluding $string from ${project.name}")
|
||||
exclude(dependency(string))
|
||||
}
|
||||
}
|
||||
|
||||
sJar.dependencies {
|
||||
exclude(dependency("org.checkerframework:checker-qual:.*"))
|
||||
exclude(dependency("org.jetbrains:annotations:.*"))
|
||||
}
|
||||
}
|
||||
}
|
||||
named("build") {
|
||||
dependsOn(shadowJar)
|
||||
}
|
||||
}
|
||||
157
build.gradle.kts
157
build.gradle.kts
@@ -1,147 +1,24 @@
|
||||
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.+"
|
||||
`java-library`
|
||||
id("floodgate-modded.build-logic")
|
||||
alias(libs.plugins.lombok) apply false
|
||||
}
|
||||
|
||||
loom {
|
||||
accessWidenerPath = file("src/main/resources/floodgate.accesswidener")
|
||||
val platforms = setOf(
|
||||
projects.fabric,
|
||||
projects.neoforge,
|
||||
projects.mod
|
||||
).map { it.dependencyProject }
|
||||
|
||||
subprojects {
|
||||
apply {
|
||||
plugin("java-library")
|
||||
plugin("io.freefair.lombok")
|
||||
plugin("floodgate-modded.build-logic")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//to change the versions see the gradle.properties file
|
||||
minecraft("com.mojang:minecraft:1.21")
|
||||
mappings(loom.officialMojangMappings())
|
||||
modImplementation("net.fabricmc:fabric-loader:0.15.11")
|
||||
|
||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||
modImplementation("net.fabricmc.fabric-api:fabric-api:0.100.1+1.21")
|
||||
|
||||
// Base Floodgate
|
||||
implementation("org.geysermc.floodgate:core:2.2.3-20240508.151752-4")
|
||||
shadow("org.geysermc.floodgate:core:2.2.3-20240508.151752-4") { isTransitive = false }
|
||||
shadow("org.geysermc.floodgate:api:2.2.3-20240508.151752-4") { 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
|
||||
|
||||
// Geyser dependency for the fun injector mixin :)))
|
||||
modCompileOnly("org.geysermc.geyser:fabric:2.2.3-SNAPSHOT") { isTransitive = false }
|
||||
|
||||
// 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(shadowJar.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.21")
|
||||
|
||||
loaders.add("fabric")
|
||||
|
||||
dependencies {
|
||||
required.project("fabric-api")
|
||||
when (this) {
|
||||
in platforms -> plugins.apply("floodgate-modded.platform-conventions")
|
||||
else -> plugins.apply("floodgate-modded.base-conventions")
|
||||
}
|
||||
}
|
||||
46
fabric/build.gradle.kts
Normal file
46
fabric/build.gradle.kts
Normal file
@@ -0,0 +1,46 @@
|
||||
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")) { 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)
|
||||
}
|
||||
|
||||
tasks {
|
||||
remapJar {
|
||||
archiveBaseName.set("floodgate-fabric")
|
||||
}
|
||||
|
||||
modrinth {
|
||||
loaders.add("fabric")
|
||||
}
|
||||
}
|
||||
1
fabric/gradle.properties
Normal file
1
fabric/gradle.properties
Normal file
@@ -0,0 +1 @@
|
||||
loom.platform=fabric
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.geysermc.floodgate.mod.util.fabric;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
public class MixinConfigPluginImpl {
|
||||
|
||||
public static boolean isGeyserLoaded() {
|
||||
return FabricLoader.getInstance().isModLoaded("geyser-fabric");
|
||||
}
|
||||
|
||||
public static boolean applyProxyFix() {
|
||||
return FabricLoader.getInstance().isModLoaded("fabricproxy-lite");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.geysermc.floodgate.platform.fabric;
|
||||
|
||||
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.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 java.nio.file.Path;
|
||||
|
||||
public final class FabricFloodgateMod extends FloodgateMod implements ModInitializer {
|
||||
|
||||
private ModContainer 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()
|
||||
);
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register(this::enable);
|
||||
|
||||
if (isClient()) {
|
||||
ClientLifecycleEvents.CLIENT_STOPPING.register($ -> this.disable());
|
||||
} else {
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register($ -> this.disable());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Path resourcePath(String file) {
|
||||
return container.findPath(file).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClient() {
|
||||
return FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.geysermc.floodgate.platform.fabric.listener;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
import org.geysermc.floodgate.core.platform.listener.ListenerRegistration;
|
||||
import org.geysermc.floodgate.mod.listener.ModEventListener;
|
||||
|
||||
public final class FabricEventRegistration implements ListenerRegistration<ModEventListener> {
|
||||
@Override
|
||||
public void register(ModEventListener listener) {
|
||||
ServerPlayConnectionEvents.JOIN.register(
|
||||
(handler, sender, server) -> listener.onPlayerJoin(handler.getPlayer().getUUID())
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,15 @@
|
||||
package org.geysermc.floodgate.module;
|
||||
package org.geysermc.floodgate.platform.fabric.module;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
import lombok.SneakyThrows;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
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.geysermc.floodgate.core.module.CommandModule;
|
||||
import org.geysermc.floodgate.core.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.core.player.FloodgateCommandPreprocessor;
|
||||
import org.geysermc.floodgate.core.player.UserAudience;
|
||||
import org.geysermc.floodgate.core.player.audience.FloodgateSenderMapper;
|
||||
import org.geysermc.floodgate.mod.util.ModCommandUtil;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.execution.ExecutionCoordinator;
|
||||
import org.incendo.cloud.fabric.FabricCommandManager;
|
||||
@@ -23,6 +25,7 @@ public final class FabricCommandModule extends CommandModule {
|
||||
new FloodgateSenderMapper<>(commandUtil)
|
||||
);
|
||||
commandManager.registerCommandPreProcessor(new FloodgateCommandPreprocessor<>(commandUtil));
|
||||
((ModCommandUtil) commandUtil).setCommandManager(commandManager);
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package org.geysermc.floodgate.platform.fabric.module;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import org.geysermc.floodgate.core.platform.listener.ListenerRegistration;
|
||||
import org.geysermc.floodgate.core.platform.pluginmessage.PluginMessageUtils;
|
||||
import org.geysermc.floodgate.core.pluginmessage.PluginMessageRegistration;
|
||||
import org.geysermc.floodgate.mod.listener.ModEventListener;
|
||||
import org.geysermc.floodgate.mod.module.ModPlatformModule;
|
||||
import org.geysermc.floodgate.platform.fabric.listener.FabricEventRegistration;
|
||||
import org.geysermc.floodgate.platform.fabric.pluginmessage.FabricPluginMessageRegistration;
|
||||
import org.geysermc.floodgate.platform.fabric.pluginmessage.FabricPluginMessageUtils;
|
||||
|
||||
public class FabricPlatformModule extends ModPlatformModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public ListenerRegistration<ModEventListener> listenerRegistration() {
|
||||
return new FabricEventRegistration();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public PluginMessageUtils pluginMessageUtils() {
|
||||
return new FabricPluginMessageUtils();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public PluginMessageRegistration pluginMessageRegister() {
|
||||
return new FabricPluginMessageRegistration();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("implementationName")
|
||||
public String implementationName() {
|
||||
return "Fabric";
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
package org.geysermc.floodgate.pluginmessage;
|
||||
package org.geysermc.floodgate.platform.fabric.pluginmessage;
|
||||
|
||||
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
|
||||
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 org.geysermc.floodgate.core.pluginmessage.PluginMessageChannel;
|
||||
import org.geysermc.floodgate.core.pluginmessage.PluginMessageRegistration;
|
||||
import org.geysermc.floodgate.mod.pluginmessage.payloads.FormPayload;
|
||||
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 {
|
||||
@Override
|
||||
@@ -1,21 +1,14 @@
|
||||
package org.geysermc.floodgate.pluginmessage;
|
||||
package org.geysermc.floodgate.platform.fabric.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 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;
|
||||
import org.geysermc.floodgate.mod.pluginmessage.payloads.TransferPayload;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
30
fabric/src/main/resources/fabric.mod.json
Normal file
30
fabric/src/main/resources/fabric.mod.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "$id",
|
||||
"version": "$version",
|
||||
"name": "$name",
|
||||
"description": "$description",
|
||||
"authors": [
|
||||
"$author"
|
||||
],
|
||||
"contact": {
|
||||
"website": "$url",
|
||||
"repo": "https://github.com/GeyserMC/Floodgate-Modded"
|
||||
},
|
||||
"license": "MIT",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"org.geysermc.floodgate.platform.fabric.FabricFloodgateMod"
|
||||
]
|
||||
},
|
||||
"accessWidener": "floodgate.accesswidener",
|
||||
"mixins": [
|
||||
"floodgate.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.15.10",
|
||||
"fabric": "*",
|
||||
"minecraft": ">=$minecraft_version"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
# Done to increase the memory available to gradle.
|
||||
org.gradle.jvmargs=-Xmx2G
|
||||
org.gradle.daemon=false
|
||||
org.gradle.caching=true
|
||||
org.gradle.vfs.watch=false
|
||||
|
||||
# Mod Properties
|
||||
version=2.2.3-SNAPSHOT
|
||||
version=2.2.4-SNAPSHOT
|
||||
group=org.geysermc.floodgate
|
||||
archives_base_name=floodgate-fabric
|
||||
id=floodgate-modded
|
||||
|
||||
57
gradle/libs.versions.toml
Normal file
57
gradle/libs.versions.toml
Normal file
@@ -0,0 +1,57 @@
|
||||
[versions]
|
||||
geyser = "2.2.3-SNAPSHOT"
|
||||
blossom = "1.2.0"
|
||||
indra = "3.1.3"
|
||||
shadow = "8.1.1"
|
||||
architectury-plugin = "3.4-SNAPSHOT"
|
||||
architectury-loom = "1.7-SNAPSHOT"
|
||||
minecraft-version = "1.21"
|
||||
minotaur = "2.+"
|
||||
guice = "6.0.0"
|
||||
cloud = "2.0.0-beta.7"
|
||||
lombok = "8.6"
|
||||
bstats = "3.0.2"
|
||||
configutils = "1.0-SNAPSHOT"
|
||||
mixin = "0.8.5"
|
||||
asm = "5.2"
|
||||
floodgate = "core-repackage-2.2.3-SNAPSHOT"
|
||||
|
||||
# fabric
|
||||
fabric-loader = "0.15.11"
|
||||
fabric-api = "0.100.1+1.21"
|
||||
|
||||
# neoforge
|
||||
neoforge-version = "21.0.87-beta"
|
||||
|
||||
[libraries]
|
||||
floodgate-core = { group = "org.geysermc.floodgate", name = "core", version.ref = "floodgate" }
|
||||
floodgate-api = { group = "org.geysermc.floodgate", name = "api", version.ref = "floodgate" }
|
||||
|
||||
geyser-fabric = { group = "org.geysermc.geyser", name = "fabric", version.ref = "geyser" }
|
||||
geyser-mod = { group = "org.geysermc.geyser", name = "mod", version.ref = "geyser" }
|
||||
geyser-core = { group = "org.geysermc.geyser", name = "core", version.ref = "geyser" }
|
||||
indra = { group = "net.kyori", name = "indra-common", version.ref = "indra" }
|
||||
shadow = { group = "com.github.johnrengelman", name = "shadow", version.ref = "shadow" }
|
||||
architectury-plugin = { group = "architectury-plugin", name = "architectury-plugin.gradle.plugin", version.ref = "architectury-plugin" }
|
||||
architectury-loom = { group = "dev.architectury.loom", name = "dev.architectury.loom.gradle.plugin", version.ref = "architectury-loom" }
|
||||
guice = { group = "com.google.inject", name = "guice", version.ref = "guice" }
|
||||
bstats = { group = "org.bstats", name = "bstats-base", version.ref = "bstats" }
|
||||
configutils = { group = "org.geysermc.configutils", name = "configutils", version.ref = "configutils" }
|
||||
cloud-fabric = { group = "org.incendo", name = "cloud-fabric", version.ref = "cloud" }
|
||||
cloud-neoforge = { group = "org.incendo", name = "cloud-neoforge", version.ref = "cloud" }
|
||||
minotaur = { group = "com.modrinth.minotaur", name = "Minotaur", version.ref = "minotaur" }
|
||||
mixin = { group = "org.spongepowered", name = "mixin", version.ref = "mixin" }
|
||||
asm = { group = "org.ow2.asm", name = "asm-debug-all", version.ref = "asm" }
|
||||
minecraft = { group = "com.mojang", name = "minecraft", version.ref = "minecraft-version" }
|
||||
|
||||
# Fabric
|
||||
fabric-loader = { group = "net.fabricmc", name = "fabric-loader", version.ref = "fabric-loader" }
|
||||
fabric-api = { group = "net.fabricmc.fabric-api", name = "fabric-api", version.ref = "fabric-api" }
|
||||
|
||||
# NeoForge
|
||||
neoforge = { group = "net.neoforged", name = "neoforge", version.ref = "neoforge-version" }
|
||||
|
||||
[plugins]
|
||||
lombok = { id = "io.freefair.lombok", version.ref = "lombok" }
|
||||
blossom = { id = "net.kyori.blossom", version.ref = "blossom"}
|
||||
indra = { id = "net.kyori.indra", version.ref = "indra" }
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
51
gradlew
vendored
51
gradlew
vendored
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright <EFBFBD> 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 <EFBFBD>$var<EFBFBD>, <EFBFBD>${var}<EFBFBD>, <EFBFBD>${var:-default}<EFBFBD>, <EFBFBD>${var+SET}<EFBFBD>,
|
||||
# <EFBFBD>${var#prefix}<EFBFBD>, <EFBFBD>${var%suffix}<EFBFBD>, and <EFBFBD>$( cmd )<EFBFBD>;
|
||||
# * compound commands having a testable exit status, especially <EFBFBD>case<EFBFBD>;
|
||||
# * various built-in commands including <EFBFBD>command<EFBFBD>, <EFBFBD>set<EFBFBD>, and <EFBFBD>ulimit<EFBFBD>.
|
||||
# * 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:
|
||||
#
|
||||
@@ -55,7 +55,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -80,13 +80,11 @@ do
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@@ -133,22 +131,29 @@ location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
@@ -205,6 +214,12 @@ set -- \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
|
||||
31
gradlew.bat
vendored
31
gradlew.bat
vendored
@@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@@ -40,13 +41,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -56,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
33
mod/build.gradle.kts
Normal file
33
mod/build.gradle.kts
Normal file
@@ -0,0 +1,33 @@
|
||||
architectury {
|
||||
common("neoforge", "fabric")
|
||||
}
|
||||
|
||||
loom {
|
||||
accessWidenerPath = file("src/main/resources/floodgate.accesswidener")
|
||||
mixin.defaultRefmapName.set("floodgate-refmap.json")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(libs.floodgate.core)
|
||||
api(libs.floodgate.api)
|
||||
api(libs.guice)
|
||||
|
||||
compileOnly(libs.mixin)
|
||||
compileOnly(libs.asm)
|
||||
modCompileOnly(libs.geyser.mod) { isTransitive = false }
|
||||
modCompileOnly(libs.geyser.core) { isTransitive = false }
|
||||
|
||||
// Only here to suppress "unknown enum constant EnvType.CLIENT" warnings.
|
||||
compileOnly(libs.fabric.loader)
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
// We don't need these
|
||||
tasks.named("remapModrinthJar").configure {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
tasks.named("modrinth").configure {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package org.geysermc.floodgate.mod;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Module;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.core.FloodgatePlatform;
|
||||
import org.geysermc.floodgate.mod.module.ModAddonModule;
|
||||
import org.geysermc.floodgate.mod.module.ModListenerModule;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public abstract class FloodgateMod {
|
||||
public static FloodgateMod INSTANCE;
|
||||
|
||||
private boolean started;
|
||||
private FloodgatePlatform platform;
|
||||
protected Injector injector;
|
||||
|
||||
protected void init(Module... modules) {
|
||||
INSTANCE = this;
|
||||
injector = Guice.createInjector(modules);
|
||||
platform = injector.getInstance(FloodgatePlatform.class);
|
||||
}
|
||||
|
||||
protected void enable(MinecraftServer server) {
|
||||
long ctm = System.currentTimeMillis();
|
||||
|
||||
// Stupid hack, see the class for more information
|
||||
// This can probably be Guice-i-fied but that is beyond me
|
||||
MinecraftServerHolder.set(server);
|
||||
|
||||
if (!started) {
|
||||
platform.enable(
|
||||
new ModAddonModule(),
|
||||
new ModListenerModule()
|
||||
);
|
||||
started = true;
|
||||
}
|
||||
|
||||
long endCtm = System.currentTimeMillis();
|
||||
injector.getInstance(FloodgateLogger.class)
|
||||
.translatedInfo("floodgate.core.finish", endCtm - ctm);
|
||||
}
|
||||
|
||||
protected void disable() {
|
||||
platform.disable();
|
||||
}
|
||||
|
||||
protected void enable(Module... module) {
|
||||
platform.enable(module);
|
||||
}
|
||||
|
||||
public @Nullable abstract Path resourcePath(String file);
|
||||
|
||||
public abstract boolean isClient();
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.geysermc.floodgate;
|
||||
package org.geysermc.floodgate.mod;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package org.geysermc.floodgate.addon.data;
|
||||
package org.geysermc.floodgate.mod.data;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.util.AttributeKey;
|
||||
import org.geysermc.floodgate.api.SimpleFloodgateApi;
|
||||
import org.geysermc.floodgate.api.inject.InjectorAddon;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.player.FloodgateHandshakeHandler;
|
||||
import org.geysermc.floodgate.util.Utils;
|
||||
import org.geysermc.floodgate.core.api.SimpleFloodgateApi;
|
||||
import org.geysermc.floodgate.core.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.core.player.FloodgateHandshakeHandler;
|
||||
import org.geysermc.floodgate.core.util.Utils;
|
||||
|
||||
public final class FabricDataAddon implements InjectorAddon {
|
||||
public final class ModDataAddon implements InjectorAddon {
|
||||
@Inject private FloodgateHandshakeHandler handshakeHandler;
|
||||
@Inject private FloodgateConfig config;
|
||||
@Inject private SimpleFloodgateApi api;
|
||||
@@ -34,7 +34,7 @@ public final class FabricDataAddon implements InjectorAddon {
|
||||
public void onInject(Channel channel, boolean toServer) {
|
||||
channel.pipeline().addBefore(
|
||||
packetHandlerName, "floodgate_data_handler",
|
||||
new FabricDataHandler(handshakeHandler, config, kickMessageAttribute, logger)
|
||||
new ModDataHandler(handshakeHandler, config, kickMessageAttribute, logger)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package org.geysermc.floodgate.addon.data;
|
||||
package org.geysermc.floodgate.mod.data;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||
import com.mojang.logging.LogUtils;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.util.AttributeKey;
|
||||
import net.minecraft.DefaultUncaughtExceptionHandler;
|
||||
import net.minecraft.network.Connection;
|
||||
@@ -10,28 +12,28 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.handshake.ClientIntentionPacket;
|
||||
import net.minecraft.network.protocol.login.ServerboundHelloPacket;
|
||||
import net.minecraft.server.network.ServerLoginPacketListenerImpl;
|
||||
import org.geysermc.floodgate.MinecraftServerHolder;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.mixin.ConnectionMixin;
|
||||
import org.geysermc.floodgate.mixin.ClientIntentionPacketMixinInterface;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.player.FloodgateHandshakeHandler;
|
||||
import org.geysermc.floodgate.player.FloodgateHandshakeHandler.HandshakeResult;
|
||||
import org.geysermc.floodgate.core.addon.data.CommonDataHandler;
|
||||
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.mod.mixin.ClientIntentionPacketMixinInterface;
|
||||
import org.geysermc.floodgate.mod.mixin.ConnectionMixin;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
public final class FabricDataHandler extends CommonDataHandler {
|
||||
public final class ModDataHandler extends CommonDataHandler {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
private final FloodgateLogger logger;
|
||||
private Connection networkManager;
|
||||
private FloodgatePlayer player;
|
||||
|
||||
public FabricDataHandler(
|
||||
public ModDataHandler(
|
||||
FloodgateHandshakeHandler handshakeHandler,
|
||||
FloodgateConfig config,
|
||||
AttributeKey<String> kickMessageAttribute, FloodgateLogger logger) {
|
||||
@@ -1,19 +1,21 @@
|
||||
package org.geysermc.floodgate.inject.fabric;
|
||||
package org.geysermc.floodgate.mod.inject;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.inject.CommonPlatformInjector;
|
||||
import org.geysermc.floodgate.core.inject.CommonPlatformInjector;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class FabricInjector extends CommonPlatformInjector {
|
||||
public final class ModInjector extends CommonPlatformInjector {
|
||||
|
||||
@Setter @Getter
|
||||
private static FabricInjector instance;
|
||||
public static ModInjector INSTANCE = new ModInjector();
|
||||
|
||||
@Getter private final boolean injected = true;
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
package org.geysermc.floodgate.listener;
|
||||
package org.geysermc.floodgate.mod.listener;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
import org.geysermc.floodgate.core.util.LanguageManager;
|
||||
|
||||
public final class FabricEventListener {
|
||||
import java.util.UUID;
|
||||
|
||||
public final class ModEventListener {
|
||||
@Inject private FloodgateApi api;
|
||||
@Inject private FloodgateLogger logger;
|
||||
@Inject private LanguageManager languageManager;
|
||||
|
||||
public void onPlayerJoin(ServerGamePacketListenerImpl networkHandler, PacketSender packetSender, MinecraftServer server) {
|
||||
FloodgatePlayer player = api.getPlayer(networkHandler.player.getUUID());
|
||||
public void onPlayerJoin(UUID uuid) {
|
||||
FloodgatePlayer player = api.getPlayer(uuid);
|
||||
if (player != null) {
|
||||
logger.translatedInfo(
|
||||
"floodgate.ingame.login_name",
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.geysermc.floodgate.logger;
|
||||
package org.geysermc.floodgate.mod.logger;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
@@ -7,10 +7,10 @@ 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 org.geysermc.floodgate.core.config.FloodgateConfig;
|
||||
import org.geysermc.floodgate.core.util.LanguageManager;
|
||||
|
||||
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
||||
import static org.geysermc.floodgate.core.util.MessageFormatter.format;
|
||||
|
||||
@Singleton
|
||||
public final class Log4jFloodgateLogger implements FloodgateLogger {
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.geysermc.floodgate.mixin;
|
||||
package org.geysermc.floodgate.mod.mixin;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.geysermc.floodgate.mixin;
|
||||
package org.geysermc.floodgate.mod.mixin;
|
||||
|
||||
import net.minecraft.network.protocol.handshake.ClientIntentionPacket;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.geysermc.floodgate.mixin;
|
||||
package org.geysermc.floodgate.mod.mixin;
|
||||
|
||||
import net.minecraft.network.protocol.handshake.ClientIntentionPacket;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.geysermc.floodgate.mixin;
|
||||
package org.geysermc.floodgate.mod.mixin;
|
||||
|
||||
import net.minecraft.network.Connection;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.geysermc.floodgate.mod.mixin;
|
||||
|
||||
import org.geysermc.floodgate.core.util.Utils;
|
||||
import org.geysermc.floodgate.mod.FloodgateMod;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Mixins into Floodgate's {@link Utils} class to modify how resources are loaded from the jar.
|
||||
* This must be done due to mod platforms sharing a classloader across mods - this leads to Floodgate
|
||||
* loading Geyser's language files, as they're not prefixed to avoid conflicts.
|
||||
* To resolve this, this mixin replaces those calls with the platform-appropriate methods to load files.
|
||||
*/
|
||||
@Mixin(value = Utils.class, remap = false)
|
||||
public class FloodgateUtilMixin {
|
||||
|
||||
@Redirect(method = "readProperties",
|
||||
at = @At(value = "INVOKE", target = "Ljava/lang/ClassLoader;getResourceAsStream(Ljava/lang/String;)Ljava/io/InputStream;"))
|
||||
private static InputStream floodgate$redirectInputStream(ClassLoader instance, String string) {
|
||||
Path path = FloodgateMod.INSTANCE.resourcePath(string);
|
||||
try {
|
||||
return path == null ? null : Files.newInputStream(path);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "getGeneratedClassesForAnnotation(Ljava/lang/String;)Ljava/util/Set;",
|
||||
at = @At(value = "INVOKE", target = "Ljava/lang/ClassLoader;getResourceAsStream(Ljava/lang/String;)Ljava/io/InputStream;"))
|
||||
private static InputStream floodgate$redirectInputStreamAnnotation(ClassLoader instance, String string) {
|
||||
Path path = FloodgateMod.INSTANCE.resourcePath(string);
|
||||
|
||||
if (path == null) {
|
||||
throw new IllegalStateException("Unable to find annotation class! " + string);
|
||||
}
|
||||
|
||||
try {
|
||||
return Files.newInputStream(path);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.geysermc.floodgate.mixin;
|
||||
package org.geysermc.floodgate.mod.mixin;
|
||||
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import org.geysermc.floodgate.inject.fabric.FabricInjector;
|
||||
import org.geysermc.floodgate.mod.inject.ModInjector;
|
||||
import org.geysermc.geyser.GeyserBootstrap;
|
||||
import org.geysermc.geyser.platform.mod.GeyserModInjector;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -19,7 +19,7 @@ public class GeyserModInjectorMixin {
|
||||
private List<ChannelFuture> allServerChannels;
|
||||
|
||||
@Inject(method = "initializeLocalChannel0", at = @At(value = "INVOKE_ASSIGN", target = "Ljava/util/List;add(Ljava/lang/Object;)Z"))
|
||||
public void onChannelAdd(GeyserBootstrap bootstrap, CallbackInfo ci) {
|
||||
FabricInjector.getInstance().injectClient(this.allServerChannels.get(this.allServerChannels.size() - 1));
|
||||
public void floodgate$onChannelAdd(GeyserBootstrap bootstrap, CallbackInfo ci) {
|
||||
ModInjector.INSTANCE.injectClient(this.allServerChannels.get(this.allServerChannels.size() - 1));
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.geysermc.floodgate.mixin;
|
||||
package org.geysermc.floodgate.mod.mixin;
|
||||
|
||||
import net.minecraft.server.network.ServerConnectionListener;
|
||||
import org.geysermc.floodgate.inject.fabric.FabricInjector;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import net.minecraft.server.network.ServerConnectionListener;
|
||||
import org.geysermc.floodgate.mod.inject.ModInjector;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -19,7 +19,7 @@ public abstract class ServerConnectionListenerMixin {
|
||||
@Shadow @Final private List<ChannelFuture> channels;
|
||||
|
||||
@Inject(method = "startTcpServerListener", at = @At(value = "INVOKE_ASSIGN", target = "Ljava/util/List;add(Ljava/lang/Object;)Z"))
|
||||
public void onChannelAdd(InetAddress address, int port, CallbackInfo ci) {
|
||||
FabricInjector.getInstance().injectClient(this.channels.get(this.channels.size() - 1));
|
||||
public void floodgate$onChannelAdd(InetAddress address, int port, CallbackInfo ci) {
|
||||
ModInjector.INSTANCE.injectClient(this.channels.get(this.channels.size() - 1));
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
package org.geysermc.floodgate.module;
|
||||
package org.geysermc.floodgate.mod.module;
|
||||
|
||||
import org.geysermc.floodgate.addon.data.FabricDataAddon;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.multibindings.ProvidesIntoSet;
|
||||
import org.geysermc.floodgate.addon.AddonManagerAddon;
|
||||
import org.geysermc.floodgate.addon.DebugAddon;
|
||||
import org.geysermc.floodgate.api.inject.InjectorAddon;
|
||||
import org.geysermc.floodgate.register.AddonRegister;
|
||||
import org.geysermc.floodgate.core.addon.AddonManagerAddon;
|
||||
import org.geysermc.floodgate.core.addon.DebugAddon;
|
||||
import org.geysermc.floodgate.core.register.AddonRegister;
|
||||
import org.geysermc.floodgate.mod.data.ModDataAddon;
|
||||
|
||||
public final class FabricAddonModule extends AbstractModule {
|
||||
public final class ModAddonModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(AddonRegister.class).asEagerSingleton();
|
||||
@@ -24,7 +24,7 @@ public final class FabricAddonModule extends AbstractModule {
|
||||
@Singleton
|
||||
@ProvidesIntoSet
|
||||
public InjectorAddon dataAddon() {
|
||||
return new FabricDataAddon();
|
||||
return new ModDataAddon();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.geysermc.floodgate.mod.module;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.multibindings.ProvidesIntoSet;
|
||||
import org.geysermc.floodgate.core.register.ListenerRegister;
|
||||
import org.geysermc.floodgate.mod.listener.ModEventListener;
|
||||
|
||||
public final class ModListenerModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(new TypeLiteral<ListenerRegister<ModEventListener>>() {}).asEagerSingleton();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@ProvidesIntoSet
|
||||
public ModEventListener modEventListener() {
|
||||
return new ModEventListener();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
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 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;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("packetEncoder")
|
||||
public String packetEncoder() {
|
||||
return FloodgateMod.INSTANCE.isClient() ? "encoder" : "outbound_config";
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("packetDecoder")
|
||||
public String packetDecoder() {
|
||||
return FloodgateMod.INSTANCE.isClient() ? "inbound_config" : "decoder" ;
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("packetHandler")
|
||||
public String packetHandler() {
|
||||
return "packet_handler";
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public SkinApplier skinApplier() {
|
||||
return new ModSkinApplier();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.geysermc.floodgate.pluginmessage;
|
||||
package org.geysermc.floodgate.mod.pluginmessage;
|
||||
|
||||
import com.mojang.authlib.properties.Property;
|
||||
import com.mojang.authlib.properties.PropertyMap;
|
||||
@@ -8,16 +8,16 @@ 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 static org.geysermc.floodgate.api.event.skin.SkinApplyEvent.SkinData;
|
||||
import org.geysermc.floodgate.core.skin.SkinApplier;
|
||||
import org.geysermc.floodgate.mod.MinecraftServerHolder;
|
||||
import org.geysermc.floodgate.mod.mixin.ChunkMapMixin;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public final class FabricSkinApplier implements SkinApplier {
|
||||
import static org.geysermc.floodgate.api.event.skin.SkinApplyEvent.SkinData;
|
||||
|
||||
public final class ModSkinApplier implements SkinApplier {
|
||||
|
||||
@Override
|
||||
public void applySkin(@NonNull FloodgatePlayer floodgatePlayer, @NonNull SkinData skinData) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.geysermc.floodgate.pluginmessage.payloads;
|
||||
package org.geysermc.floodgate.mod.pluginmessage.payloads;
|
||||
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.geysermc.floodgate.pluginmessage.payloads;
|
||||
package org.geysermc.floodgate.mod.pluginmessage.payloads;
|
||||
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.geysermc.floodgate.pluginmessage.payloads;
|
||||
package org.geysermc.floodgate.mod.pluginmessage.payloads;
|
||||
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.geysermc.floodgate.pluginmessage.payloads;
|
||||
package org.geysermc.floodgate.mod.pluginmessage.payloads;
|
||||
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
@@ -1,28 +1,30 @@
|
||||
package org.geysermc.floodgate.util;
|
||||
package org.geysermc.floodgate.mod.util;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||
import net.minecraft.commands.CommandSource;
|
||||
import lombok.Setter;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.SharedSuggestionProvider;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.players.UserWhiteListEntry;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.geysermc.floodgate.MinecraftServerHolder;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
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.*;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class FabricCommandUtil extends CommandUtil {
|
||||
public final class ModCommandUtil extends CommandUtil {
|
||||
private final FloodgateLogger logger;
|
||||
private UserAudience console;
|
||||
@Setter
|
||||
private CommandManager<UserAudience> commandManager;
|
||||
|
||||
public FabricCommandUtil(LanguageManager manager, FloodgateApi api, FloodgateLogger logger) {
|
||||
public ModCommandUtil(LanguageManager manager, FloodgateApi api, FloodgateLogger logger) {
|
||||
super(manager, api);
|
||||
this.logger = logger;
|
||||
}
|
||||
@@ -73,8 +75,7 @@ public final class FabricCommandUtil extends CommandUtil {
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(Object source, String permission) {
|
||||
return Permissions.check((SharedSuggestionProvider) source,
|
||||
permission, MinecraftServerHolder.get().getOperatorUserPermissionLevel());
|
||||
return commandManager.hasPermission(getUserAudience(source), permission);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,6 +1,6 @@
|
||||
package org.geysermc.floodgate.util;
|
||||
package org.geysermc.floodgate.mod.util;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import dev.architectury.injectables.annotations.ExpectPlatform;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
||||
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
||||
@@ -8,7 +8,7 @@ import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class MixinConfigPlugin implements IMixinConfigPlugin {
|
||||
public class ModMixinConfigPlugin implements IMixinConfigPlugin {
|
||||
|
||||
@Override
|
||||
public void onLoad(String mixinPackage) {
|
||||
@@ -21,12 +21,11 @@ public class MixinConfigPlugin implements IMixinConfigPlugin {
|
||||
|
||||
@Override
|
||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
||||
if (mixinClassName.equals("org.geysermc.floodgate.mixin.ClientIntentionPacketMixin")) {
|
||||
//returns true if fabricproxy-lite is present, therefore loading the mixin. If not present, the mixin will not be loaded.
|
||||
return FabricLoader.getInstance().isModLoaded("fabricproxy-lite");
|
||||
if (mixinClassName.equals("org.geysermc.floodgate.mod.mixin.ClientIntentionPacketMixin")) {
|
||||
return applyProxyFix();
|
||||
}
|
||||
if (mixinClassName.equals("org.geysermc.floodgate.mixin.GeyserModInjectorMixin")) {
|
||||
return FabricLoader.getInstance().isModLoaded("geyser-fabric");
|
||||
if (mixinClassName.equals("org.geysermc.floodgate.mod.mixin.GeyserModInjectorMixin")) {
|
||||
return isGeyserLoaded();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -47,4 +46,14 @@ public class MixinConfigPlugin implements IMixinConfigPlugin {
|
||||
@Override
|
||||
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static boolean isGeyserLoaded() {
|
||||
throw new IllegalStateException("isGeyserLoaded is not implemented!");
|
||||
}
|
||||
|
||||
@ExpectPlatform
|
||||
public static boolean applyProxyFix() {
|
||||
throw new IllegalStateException("applyProxyFix is not implemented!");
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
package org.geysermc.floodgate.util;
|
||||
package org.geysermc.floodgate.mod.util;
|
||||
|
||||
import net.minecraft.SharedConstants;
|
||||
import org.geysermc.floodgate.MinecraftServerHolder;
|
||||
import org.geysermc.floodgate.platform.util.PlatformUtils;
|
||||
import org.geysermc.floodgate.core.platform.util.PlatformUtils;
|
||||
import org.geysermc.floodgate.mod.MinecraftServerHolder;
|
||||
|
||||
public class FabricPlatformUtils extends PlatformUtils {
|
||||
public class ModPlatformUtils extends PlatformUtils {
|
||||
@Override
|
||||
public AuthType authType() {
|
||||
return MinecraftServerHolder.get().usesAuthentication() ? AuthType.ONLINE : AuthType.OFFLINE;
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.geysermc.floodgate.mod.util;
|
||||
|
||||
import org.geysermc.configutils.file.template.TemplateReader;
|
||||
import org.geysermc.floodgate.mod.FloodgateMod;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class ModTemplateReader implements TemplateReader {
|
||||
|
||||
@Override
|
||||
public BufferedReader read(String configName) {
|
||||
Path path = FloodgateMod.INSTANCE.resourcePath(configName);
|
||||
if (path != null) {
|
||||
try {
|
||||
return Files.newBufferedReader(path);
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,18 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "org.geysermc.floodgate.mixin",
|
||||
"package": "org.geysermc.floodgate.mod.mixin",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"ChunkMapMixin",
|
||||
"ClientIntentionPacketMixin",
|
||||
"ClientIntentionPacketMixinInterface",
|
||||
"ConnectionMixin",
|
||||
"FloodgateUtilMixin",
|
||||
"GeyserModInjectorMixin",
|
||||
"ServerConnectionListenerMixin"
|
||||
],
|
||||
"plugin": "org.geysermc.floodgate.util.MixinConfigPlugin",
|
||||
"plugin": "org.geysermc.floodgate.mod.util.ModMixinConfigPlugin",
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
61
neoforge/build.gradle.kts
Normal file
61
neoforge/build.gradle.kts
Normal file
@@ -0,0 +1,61 @@
|
||||
architectury {
|
||||
platformSetupLoomIde()
|
||||
neoForge()
|
||||
}
|
||||
|
||||
provided("com.google.guava", "failureaccess")
|
||||
|
||||
// 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 developmentNeoForge: Configuration = configurations.getByName("developmentNeoForge")
|
||||
// Our custom transitive include configuration
|
||||
val includeTransitive: Configuration = configurations.getByName("includeTransitive")
|
||||
|
||||
configurations {
|
||||
compileClasspath.get().extendsFrom(configurations["common"])
|
||||
runtimeClasspath.get().extendsFrom(configurations["common"])
|
||||
developmentNeoForge.extendsFrom(configurations["common"])
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// See https://github.com/google/guava/issues/6618
|
||||
modules {
|
||||
module("com.google.guava:listenablefuture") {
|
||||
replacedBy("com.google.guava:guava", "listenablefuture is part of guava")
|
||||
}
|
||||
}
|
||||
|
||||
neoForge(libs.neoforge)
|
||||
// "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 = "transformProductionNeoForge")) { isTransitive = false }
|
||||
|
||||
includeTransitive(libs.floodgate.core)
|
||||
|
||||
implementation(libs.floodgate.core)
|
||||
implementation(libs.guice)
|
||||
|
||||
modImplementation(libs.cloud.neoforge)
|
||||
include(libs.cloud.neoforge)
|
||||
}
|
||||
|
||||
tasks {
|
||||
processResources {
|
||||
from(project(":mod").file("src/main/resources/floodgate.accesswidener")) {
|
||||
into("/assets/")
|
||||
}
|
||||
}
|
||||
|
||||
remapJar {
|
||||
dependsOn(processResources)
|
||||
atAccessWideners.add("floodgate.accesswidener")
|
||||
archiveBaseName.set("floodgate-neoforge")
|
||||
}
|
||||
|
||||
modrinth {
|
||||
loaders.add("neoforge")
|
||||
}
|
||||
}
|
||||
1
neoforge/gradle.properties
Normal file
1
neoforge/gradle.properties
Normal file
@@ -0,0 +1 @@
|
||||
loom.platform=neoforge
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.geysermc.floodgate.mod.util.neoforge;
|
||||
|
||||
import net.neoforged.fml.loading.LoadingModList;
|
||||
|
||||
public class ModMixinConfigPluginImpl {
|
||||
public static boolean isGeyserLoaded() {
|
||||
return LoadingModList.get().getModFileById("geyser_neoforge") != null;
|
||||
}
|
||||
|
||||
public static boolean applyProxyFix() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package org.geysermc.floodgate.platform.neoforge;
|
||||
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.fml.ModContainer;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.fml.loading.FMLLoader;
|
||||
import net.neoforged.fml.loading.FMLPaths;
|
||||
import net.neoforged.neoforge.common.NeoForge;
|
||||
import net.neoforged.neoforge.event.GameShuttingDownEvent;
|
||||
import net.neoforged.neoforge.event.server.ServerStartedEvent;
|
||||
import net.neoforged.neoforge.event.server.ServerStoppingEvent;
|
||||
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
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.neoforge.module.NeoForgeCommandModule;
|
||||
import org.geysermc.floodgate.platform.neoforge.module.NeoForgePlatformModule;
|
||||
import org.geysermc.floodgate.platform.neoforge.pluginmessage.NeoForgePluginMessageRegistration;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Mod("floodgate")
|
||||
public final class NeoForgeFloodgateMod extends FloodgateMod {
|
||||
|
||||
private final ModContainer container;
|
||||
|
||||
public NeoForgeFloodgateMod(IEventBus modEventBus, ModContainer container) {
|
||||
this.container = container;
|
||||
init(
|
||||
new ServerCommonModule(
|
||||
FMLPaths.CONFIGDIR.get().resolve("floodgate"),
|
||||
new ModTemplateReader()
|
||||
),
|
||||
new NeoForgePlatformModule(),
|
||||
new NeoForgeCommandModule()
|
||||
);
|
||||
|
||||
modEventBus.addListener(this::onRegisterPackets);
|
||||
NeoForge.EVENT_BUS.addListener(this::onServerStarted);
|
||||
if (FMLLoader.getDist().isClient()) {
|
||||
NeoForge.EVENT_BUS.addListener(this::onClientStop);
|
||||
} else {
|
||||
NeoForge.EVENT_BUS.addListener(this::onServerStop);
|
||||
}
|
||||
}
|
||||
|
||||
private void onServerStarted(ServerStartedEvent event) {
|
||||
this.enable(event.getServer());
|
||||
}
|
||||
|
||||
private void onClientStop(GameShuttingDownEvent ignored) {
|
||||
this.disable();
|
||||
}
|
||||
|
||||
private void onServerStop(ServerStoppingEvent ignored) {
|
||||
this.disable();
|
||||
}
|
||||
|
||||
private void onRegisterPackets(final RegisterPayloadHandlersEvent event) {
|
||||
// Set the registrar once we're given it - NeoForgePluginMessageRegistration was created earlier in NeoForgePlatformModule
|
||||
NeoForgePluginMessageRegistration pluginMessageRegistration = injector.getInstance(NeoForgePluginMessageRegistration.class);
|
||||
pluginMessageRegistration.setRegistrar(event.registrar("floodgate").optional());
|
||||
|
||||
// We can now trigger the registering of our plugin message channels
|
||||
enable(new PluginMessageModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Path resourcePath(String file) {
|
||||
return container.getModInfo().getOwningFile().getFile().findResource(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClient() {
|
||||
return FMLLoader.getDist().isClient();
|
||||
}
|
||||
|
||||
public Set<Class<?>> getAnnotatedClasses(Class<? extends Annotation> annotationClass) {
|
||||
return container.getModInfo()
|
||||
.getOwningFile()
|
||||
.getFile()
|
||||
.getScanResult()
|
||||
.getAnnotatedBy(annotationClass, ElementType.TYPE)
|
||||
.map(annotationData -> {
|
||||
try {
|
||||
return Class.forName(annotationData.clazz().getClassName());
|
||||
} catch (Exception e) {
|
||||
injector.getInstance(FloodgateLogger.class).error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
})
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.geysermc.floodgate.platform.neoforge.listener;
|
||||
|
||||
import net.neoforged.neoforge.common.NeoForge;
|
||||
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
|
||||
import org.geysermc.floodgate.core.platform.listener.ListenerRegistration;
|
||||
import org.geysermc.floodgate.mod.listener.ModEventListener;
|
||||
|
||||
public final class NeoForgeEventRegistration implements ListenerRegistration<ModEventListener> {
|
||||
private ModEventListener listener;
|
||||
|
||||
@Override
|
||||
public void register(ModEventListener listener) {
|
||||
NeoForge.EVENT_BUS.addListener(this::onPlayerJoin);
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
private void onPlayerJoin(PlayerEvent.PlayerLoggedInEvent event) {
|
||||
listener.onPlayerJoin(event.getEntity().getUUID());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.geysermc.floodgate.platform.neoforge.mixin;
|
||||
|
||||
import org.geysermc.floodgate.core.util.Utils;
|
||||
import org.geysermc.floodgate.mod.FloodgateMod;
|
||||
import org.geysermc.floodgate.platform.neoforge.NeoForgeFloodgateMod;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Mixin into Floodgate's {@link Utils} class as NeoForge is really picky about how it allows scanning
|
||||
* mod-owned classes.
|
||||
*/
|
||||
@Mixin(value = Utils.class, remap = false)
|
||||
public class NeoForgeFloodgateUtilMixin {
|
||||
|
||||
/**
|
||||
* @author geysermc
|
||||
* @reason NeoForge is really picky about how it allows scanning mod-owned classes.
|
||||
*/
|
||||
@Overwrite(remap = false)
|
||||
public static Set<Class<?>> getGeneratedClassesForAnnotation(Class<? extends Annotation> annotationClass) {
|
||||
return ((NeoForgeFloodgateMod) FloodgateMod.INSTANCE).getAnnotatedClasses(annotationClass);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.geysermc.floodgate.platform.neoforge.module;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
import lombok.SneakyThrows;
|
||||
import org.geysermc.floodgate.core.module.CommandModule;
|
||||
import org.geysermc.floodgate.core.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.core.player.FloodgateCommandPreprocessor;
|
||||
import org.geysermc.floodgate.core.player.UserAudience;
|
||||
import org.geysermc.floodgate.core.player.audience.FloodgateSenderMapper;
|
||||
import org.geysermc.floodgate.mod.util.ModCommandUtil;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.execution.ExecutionCoordinator;
|
||||
import org.incendo.cloud.neoforge.NeoForgeServerCommandManager;
|
||||
|
||||
public class NeoForgeCommandModule extends CommandModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
@SneakyThrows
|
||||
public CommandManager<UserAudience> commandManager(CommandUtil commandUtil) {
|
||||
CommandManager<UserAudience> commandManager = new NeoForgeServerCommandManager<>(
|
||||
ExecutionCoordinator.simpleCoordinator(),
|
||||
new FloodgateSenderMapper<>(commandUtil)
|
||||
);
|
||||
commandManager.registerCommandPreProcessor(new FloodgateCommandPreprocessor<>(commandUtil));
|
||||
((ModCommandUtil) commandUtil).setCommandManager(commandManager);
|
||||
return commandManager;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.geysermc.floodgate.platform.neoforge.module;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Scopes;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import org.geysermc.floodgate.core.platform.listener.ListenerRegistration;
|
||||
import org.geysermc.floodgate.core.platform.pluginmessage.PluginMessageUtils;
|
||||
import org.geysermc.floodgate.core.pluginmessage.PluginMessageRegistration;
|
||||
import org.geysermc.floodgate.mod.listener.ModEventListener;
|
||||
import org.geysermc.floodgate.mod.module.ModPlatformModule;
|
||||
import org.geysermc.floodgate.platform.neoforge.listener.NeoForgeEventRegistration;
|
||||
import org.geysermc.floodgate.platform.neoforge.pluginmessage.NeoForgePluginMessageRegistration;
|
||||
import org.geysermc.floodgate.platform.neoforge.pluginmessage.NeoForgePluginMessageUtils;
|
||||
|
||||
public class NeoForgePlatformModule extends ModPlatformModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
|
||||
// We retrieve using NeoForgePluginMessageRegistration.class from our the mod class.
|
||||
// We do this to ensure that injector#getInstance with either class returns the same singleton
|
||||
bind(PluginMessageRegistration.class).to(NeoForgePluginMessageRegistration.class).in(Scopes.SINGLETON);
|
||||
bind(NeoForgePluginMessageRegistration.class).toInstance(new NeoForgePluginMessageRegistration());
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public ListenerRegistration<ModEventListener> listenerRegistration() {
|
||||
return new NeoForgeEventRegistration();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public PluginMessageUtils pluginMessageUtils() {
|
||||
return new NeoForgePluginMessageUtils();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("implementationName")
|
||||
public String implementationName() {
|
||||
return "NeoForge";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.geysermc.floodgate.platform.neoforge.pluginmessage;
|
||||
|
||||
import lombok.Setter;
|
||||
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
|
||||
import org.geysermc.floodgate.core.pluginmessage.PluginMessageChannel;
|
||||
import org.geysermc.floodgate.core.pluginmessage.PluginMessageRegistration;
|
||||
import org.geysermc.floodgate.mod.pluginmessage.payloads.FormPayload;
|
||||
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 NeoForgePluginMessageRegistration implements PluginMessageRegistration {
|
||||
|
||||
@Setter
|
||||
private PayloadRegistrar registrar;
|
||||
|
||||
@Override
|
||||
public void register(PluginMessageChannel channel) {
|
||||
switch (channel.getIdentifier()) {
|
||||
case "floodgate:form" ->
|
||||
registrar.playBidirectional(FormPayload.TYPE, FormPayload.STREAM_CODEC, (payload, context) ->
|
||||
channel.handleServerCall(payload.data(), context.player().getUUID(),
|
||||
context.player().getGameProfile().getName()));
|
||||
case "floodgate:packet" ->
|
||||
registrar.playBidirectional(PacketPayload.TYPE, PacketPayload.STREAM_CODEC, (payload, context) ->
|
||||
channel.handleServerCall(payload.data(), context.player().getUUID(),
|
||||
context.player().getGameProfile().getName()));
|
||||
case "floodgate:skin" ->
|
||||
registrar.playBidirectional(SkinPayload.TYPE, SkinPayload.STREAM_CODEC, (payload, context) ->
|
||||
channel.handleServerCall(payload.data(), context.player().getUUID(),
|
||||
context.player().getGameProfile().getName()));
|
||||
case "floodgate:transfer" ->
|
||||
registrar.playBidirectional(TransferPayload.TYPE, TransferPayload.STREAM_CODEC, (payload, context) ->
|
||||
channel.handleServerCall(payload.data(), context.player().getUUID(),
|
||||
context.player().getGameProfile().getName()));
|
||||
default -> throw new IllegalArgumentException("unknown channel: " + channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package org.geysermc.floodgate.platform.neoforge.pluginmessage;
|
||||
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
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;
|
||||
import org.geysermc.floodgate.mod.pluginmessage.payloads.TransferPayload;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
public class NeoForgePluginMessageUtils extends PluginMessageUtils {
|
||||
public boolean sendMessage(UUID uuid, String channel, byte[] data) {
|
||||
try {
|
||||
ServerPlayer player = MinecraftServerHolder.get().getPlayerList().getPlayer(uuid);
|
||||
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);
|
||||
PacketDistributor.sendToPlayer(player, payload);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
27
neoforge/src/main/resources/META-INF/neoforge.mods.toml
Normal file
27
neoforge/src/main/resources/META-INF/neoforge.mods.toml
Normal file
@@ -0,0 +1,27 @@
|
||||
modLoader="javafml"
|
||||
loaderVersion="[1,)"
|
||||
license="MIT"
|
||||
[[mods]]
|
||||
modId="$id"
|
||||
version="$version"
|
||||
displayName="$name"
|
||||
displayURL="$url"
|
||||
logoFile= "../assets/floodgate/icon.png"
|
||||
authors="$author"
|
||||
description="$description"
|
||||
[[mixins]]
|
||||
config = "floodgate.mixins.json"
|
||||
[[mixins]]
|
||||
config = "floodgate_neoforge.mixins.json"
|
||||
[[dependencies.floodgate]]
|
||||
modId="neoforge"
|
||||
type="required"
|
||||
versionRange="[21.0.0-beta,)"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
[[dependencies.floodgate]]
|
||||
modId="minecraft"
|
||||
type="required"
|
||||
versionRange="[$minecraft_version,)"
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
12
neoforge/src/main/resources/floodgate_neoforge.mixins.json
Normal file
12
neoforge/src/main/resources/floodgate_neoforge.mixins.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"required": true,
|
||||
"minVersion": "0.8",
|
||||
"package": "org.geysermc.floodgate.platform.neoforge.mixin",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"NeoForgeFloodgateUtilMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,34 @@
|
||||
@file:Suppress("UnstableApiUsage")
|
||||
|
||||
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
//mavenLocal()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
maven("https://repo.opencollab.dev/main/")
|
||||
maven("https://jitpack.io") {
|
||||
content {
|
||||
includeGroupByRegex("com\\.github\\..*")
|
||||
}
|
||||
}
|
||||
|
||||
maven("https://maven.architectury.dev/")
|
||||
maven("https://maven.neoforged.net/releases")
|
||||
maven("https://maven.fabricmc.net/")
|
||||
}
|
||||
|
||||
plugins {
|
||||
id("net.kyori.blossom")
|
||||
id("net.kyori.indra")
|
||||
id("net.kyori.indra.git")
|
||||
id("floodgate-modded.build-logic")
|
||||
}
|
||||
|
||||
includeBuild("build-logic")
|
||||
}
|
||||
|
||||
rootProject.name = "floodgate-modded"
|
||||
|
||||
include(":mod")
|
||||
include(":fabric")
|
||||
include(":neoforge")
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package org.geysermc.floodgate;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import org.geysermc.floodgate.inject.fabric.FabricInjector;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.module.*;
|
||||
import org.geysermc.floodgate.util.FabricTemplateReader;
|
||||
|
||||
public class FabricMod implements ModInitializer {
|
||||
|
||||
private boolean started;
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
FabricInjector.setInstance(new FabricInjector());
|
||||
|
||||
Injector injector = Guice.createInjector(
|
||||
new ServerCommonModule(FabricLoader.getInstance().getConfigDir().resolve("floodgate"), new FabricTemplateReader()),
|
||||
new FabricPlatformModule()
|
||||
);
|
||||
|
||||
FloodgatePlatform platform = injector.getInstance(FloodgatePlatform.class);
|
||||
|
||||
platform.enable(new FabricCommandModule());
|
||||
|
||||
ServerLifecycleEvents.SERVER_STARTED.register((server) -> {
|
||||
long ctm = System.currentTimeMillis();
|
||||
|
||||
// Stupid hack, see the class for more information
|
||||
// This can probably be Guice-i-fied but that is beyond me
|
||||
MinecraftServerHolder.set(server);
|
||||
|
||||
if (!started) {
|
||||
platform.enable(
|
||||
new FabricAddonModule(),
|
||||
new FabricListenerModule(),
|
||||
new PluginMessageModule()
|
||||
);
|
||||
started = true;
|
||||
}
|
||||
|
||||
long endCtm = System.currentTimeMillis();
|
||||
injector.getInstance(FloodgateLogger.class)
|
||||
.translatedInfo("floodgate.core.finish", endCtm - ctm);
|
||||
});
|
||||
|
||||
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
|
||||
ClientLifecycleEvents.CLIENT_STOPPING.register(($) -> {
|
||||
platform.disable();
|
||||
});
|
||||
} else {
|
||||
ServerLifecycleEvents.SERVER_STOPPING.register((server) -> {
|
||||
platform.disable();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package org.geysermc.floodgate.listener;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||
import org.geysermc.floodgate.platform.listener.ListenerRegistration;
|
||||
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Inject))
|
||||
public final class FabricEventRegistration implements ListenerRegistration<FabricEventListener> {
|
||||
@Override
|
||||
public void register(FabricEventListener listener) {
|
||||
ServerPlayConnectionEvents.JOIN.register(listener::onPlayerJoin);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
package org.geysermc.floodgate.module;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.multibindings.ProvidesIntoSet;
|
||||
import org.geysermc.floodgate.listener.FabricEventListener;
|
||||
import org.geysermc.floodgate.register.ListenerRegister;
|
||||
|
||||
public final class FabricListenerModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(new TypeLiteral<ListenerRegister<FabricEventListener>>() {}).asEagerSingleton();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@ProvidesIntoSet
|
||||
public FabricEventListener fabricEventListener() {
|
||||
return new FabricEventListener();
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
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;
|
||||
import org.geysermc.floodgate.logger.Log4jFloodgateLogger;
|
||||
import org.geysermc.floodgate.platform.listener.ListenerRegistration;
|
||||
import org.geysermc.floodgate.platform.pluginmessage.PluginMessageUtils;
|
||||
import org.geysermc.floodgate.platform.util.PlatformUtils;
|
||||
import org.geysermc.floodgate.pluginmessage.FabricPluginMessageRegistration;
|
||||
import org.geysermc.floodgate.pluginmessage.FabricPluginMessageUtils;
|
||||
import org.geysermc.floodgate.pluginmessage.FabricSkinApplier;
|
||||
import org.geysermc.floodgate.pluginmessage.PluginMessageRegistration;
|
||||
import org.geysermc.floodgate.util.FabricCommandUtil;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.inject.CommonPlatformInjector;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.skin.SkinApplier;
|
||||
import org.geysermc.floodgate.util.FabricPlatformUtils;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class FabricPlatformModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(PlatformUtils.class).to(FabricPlatformUtils.class);
|
||||
bind(Logger.class).annotatedWith(Names.named("logger")).toInstance(LogManager.getLogger("floodgate"));
|
||||
bind(FloodgateLogger.class).to(Log4jFloodgateLogger.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public CommandUtil commandUtil(
|
||||
FloodgateApi api,
|
||||
FloodgateLogger logger,
|
||||
LanguageManager languageManager) {
|
||||
return new FabricCommandUtil(languageManager, api, logger);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public ListenerRegistration<FabricEventListener> listenerRegistration() {
|
||||
return new FabricEventRegistration();
|
||||
}
|
||||
|
||||
/*
|
||||
DebugAddon / PlatformInjector
|
||||
*/
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public CommonPlatformInjector platformInjector() {
|
||||
return FabricInjector.getInstance();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("packetEncoder")
|
||||
public String packetEncoder() {
|
||||
return "encoder";
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("packetDecoder")
|
||||
public String packetDecoder() {
|
||||
return "decoder";
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("packetHandler")
|
||||
public String packetHandler() {
|
||||
return "packet_handler";
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public PluginMessageUtils pluginMessageUtils() {
|
||||
return new FabricPluginMessageUtils();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Named("implementationName")
|
||||
public String implementationName() {
|
||||
return "Fabric";
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public PluginMessageRegistration pluginMessageRegister() {
|
||||
return new FabricPluginMessageRegistration();
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public SkinApplier skinApplier() {
|
||||
return new FabricSkinApplier();
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package org.geysermc.floodgate.util;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
import org.geysermc.configutils.file.template.TemplateReader;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
|
||||
public class FabricTemplateReader implements TemplateReader {
|
||||
|
||||
private final ModContainer container;
|
||||
|
||||
public FabricTemplateReader() {
|
||||
container = FabricLoader.getInstance().getModContainer("floodgate").orElseThrow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedReader read(String configName) {
|
||||
Optional<Path> optional = container.findPath(configName);
|
||||
if (optional.isPresent()) {
|
||||
try {
|
||||
InputStream stream = optional.get().getFileSystem()
|
||||
.provider()
|
||||
.newInputStream(optional.get());
|
||||
return new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "floodgate",
|
||||
"version": "${version}",
|
||||
"name": "Floodgate-Fabric",
|
||||
"description": "",
|
||||
"authors": [
|
||||
"GeyserMC"
|
||||
],
|
||||
"contact": {
|
||||
"website": "https://geysermc.org",
|
||||
"repo": "https://github.com/GeyserMC/Floodgate-Fabric"
|
||||
},
|
||||
"license": "MIT",
|
||||
"icon": "assets/floodgate/icon.png",
|
||||
"environment": "*",
|
||||
"entrypoints": {
|
||||
"main": [
|
||||
"org.geysermc.floodgate.FabricMod"
|
||||
]
|
||||
},
|
||||
"accessWidener": "floodgate.accesswidener",
|
||||
"mixins": [
|
||||
"floodgate.mixins.json"
|
||||
],
|
||||
"depends": {
|
||||
"fabricloader": ">=0.15.11",
|
||||
"fabric": "*",
|
||||
"minecraft": ">=1.21"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user