From b381df555b5ea51e07f2bfdd1c83d9f632a6e14d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD?= Date: Tue, 20 Aug 2024 22:56:35 +0300 Subject: [PATCH 01/13] NeoForge support --- gradle/verification-metadata.xml | 218 ++++++- neoforge/build.gradle.kts | 541 ++++++++++++++++++ neoforge/gradle.properties | 8 + .../mixins.spongeforge.accessors.json | 7 + .../PluginDependencyConfigurable.java | 77 +++ .../metadata/PluginFileConfigurable.java | 140 +++++ .../metadata/PluginMetadataConfigurable.java | 65 +++ .../loading/metadata/PluginMetadataUtils.java | 83 +++ .../loading/moddiscovery/ModFileParsers.java | 112 ++++ .../SpongeForgeDependencyLocator.java | 82 +++ .../moddiscovery/SpongeForgeModLocator.java | 93 +++ .../moddiscovery/library/AsyncUtils.java | 52 ++ .../moddiscovery/library/InstallerUtils.java | 169 ++++++ .../moddiscovery/library/LibraryManager.java | 246 ++++++++ .../library/model/sponge/Libraries.java | 57 ++ .../model/sponge/SonatypeResponse.java | 46 ++ .../locator/EnvironmentPluginLocator.java | 97 ++++ .../locator/PluginsDirectoryLocator.java | 94 +++ .../applaunch/plugin/ForgePluginPlatform.java | 134 +++++ .../transformation/ListenerTransformer.java | 100 ++++ .../SpongeForgeTransformationService.java | 155 +++++ ...ods.modlauncher.api.ITransformationService | 1 + ...forge.forgespi.locating.IDependencyLocator | 1 + ...necraftforge.forgespi.locating.IModLocator | 3 + .../provider/JavaPluginLanguageProvider.java | 134 +++++ ...rge.forgespi.language.IModLanguageProvider | 1 + .../forge/launch/ForgeLaunch.java | 106 ++++ .../forge/launch/ForgeMappingManager.java | 61 ++ .../forge/launch/ForgePlatform.java | 50 ++ .../bridge/event/ForgeEventBridge_Forge.java | 61 ++ .../bridge/event/SpongeEventBridge_Forge.java | 59 ++ .../launch/command/ForgeCommandManager.java | 108 ++++ .../forge/launch/event/ForgeEventManager.java | 168 ++++++ .../forge/launch/event/ListenerLookups.java | 43 ++ .../forge/launch/event/SpongeEventBus.java | 103 ++++ .../launch/inject/SpongeForgeModule.java | 47 ++ .../launch/plugin/ForgePluginContainer.java | 101 ++++ .../launch/plugin/ForgePluginManager.java | 62 ++ .../launch/plugin/PluginModContainer.java | 129 +++++ .../org/spongepowered/forge/ForgeClient.java | 31 + .../org/spongepowered/forge/ForgeEngine.java | 30 + .../org/spongepowered/forge/ForgeServer.java | 34 ++ .../org/spongepowered/forge/SpongeAPIMod.java | 31 + .../spongepowered/forge/SpongeForgeMod.java | 151 +++++ .../org/spongepowered/forge/SpongeMod.java | 31 + .../forge/hook/ForgeChannelHooks.java | 59 ++ .../forge/hook/ForgeEventHooks.java | 54 ++ .../forge/hook/ForgeGeneralHooks.java | 39 ++ .../forge/hook/ForgeItemHooks.java | 31 + .../forge/hook/ForgeWorldHooks.java | 66 +++ .../forge/world/server/ForgeWorldManager.java | 35 ++ .../resource-templates/META-INF/mods.toml | 56 ++ .../src/main/resources/forge.superclasschange | 3 + neoforge/src/main/resources/pack.mcmeta | 6 + .../MinecraftServerMixin_Forge_API.java | 49 ++ .../core/api/event/EventMixin_Forge.java | 34 ++ .../ChangeBlockEvent_AllMixin_Forge.java | 66 +++ ...ChangeEntityWorldEvent_PreMixin_Forge.java | 49 ++ ...ChangeEventWorldEvent_PostMixin_Forge.java | 53 ++ .../core/client/MinecraftMixin_Forge.java | 40 ++ .../core/client/main/MainMixin_Forge.java | 50 ++ .../core/commands/CommandsMixin_Forge.java | 101 ++++ .../MinecraftForgeMixin_Forge.java | 46 ++ ...tityTravelToDimensionEventMixin_Forge.java | 76 +++ ...layerChangedDimensionEventMixin_Forge.java | 72 +++ .../event/world/BlockEventMixin_Forge.java | 43 ++ .../BlockEvent_BreakEventMixin_Forge.java | 99 ++++ .../internal/BrandingControlMixin_Forge.java | 51 ++ .../registries/ForgeRegistryMixin_Forge.java | 88 +++ .../RegistryManagerMixin_Forge.java | 51 ++ .../core/network/ConnectionMixin_Forge.java | 46 ++ .../core/server/BootstrapMixin_Forge.java | 62 ++ .../mixin/core/server/MainMixin_Forge.java | 46 ++ .../server/MinecraftServerMixin_Forge.java | 53 ++ .../SpreadPlayersCommandMixin_Forge.java | 53 ++ .../server/level/ServerPlayerMixin_Forge.java | 51 ++ ...rverGamePacketListenerImplMixin_Forge.java | 66 +++ ...verLoginPacketListenerImplMixin_Forge.java | 50 ++ .../world/entity/LivingEntityMixin_Forge.java | 64 +++ .../LivingEntityMixin_Forge_Attack_Impl.java | 46 ++ .../entity/item/ItemEntityMixin_Forge.java | 53 ++ .../entity/player/PlayerMixin_Forge.java | 41 ++ .../ThrownEnderpealMixin_Forge.java | 44 ++ .../world/entity/vehicle/BoatMixin_Forge.java | 53 ++ .../level/block/FireBlockMixin_Forge.java | 74 +++ ...AbstractFurnaceBlockEntityMixin_Forge.java | 183 ++++++ .../level/block/entity/package-info.java | 6 + ...opperBlockEntityMixin_Inventory_Forge.java | 84 +++ .../forge/mixin/plugin/ForgeCorePlugin.java | 51 ++ ...rverPlayerGameModeMixin_Forge_Tracker.java | 82 +++ .../level/block/BlockMixin_Forge_Tracker.java | 51 ++ .../BlockBehaviorMixin_Forge_Tracker.java | 51 ++ .../resources/mixins.spongeforge.api.json | 14 + .../resources/mixins.spongeforge.core.json | 46 ++ .../mixins.spongeforge.inventory.json | 11 + .../resources/mixins.spongeforge.tracker.json | 13 + settings.gradle.kts | 16 + 97 files changed, 6843 insertions(+), 6 deletions(-) mode change 100644 => 100755 gradle/verification-metadata.xml create mode 100755 neoforge/build.gradle.kts create mode 100755 neoforge/gradle.properties create mode 100755 neoforge/src/accessors/resources/mixins.spongeforge.accessors.json create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginDependencyConfigurable.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginFileConfigurable.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataConfigurable.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataUtils.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/ModFileParsers.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeDependencyLocator.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeModLocator.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/AsyncUtils.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/InstallerUtils.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/LibraryManager.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/Libraries.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/SonatypeResponse.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/EnvironmentPluginLocator.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/PluginsDirectoryLocator.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/plugin/ForgePluginPlatform.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/ListenerTransformer.java create mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/SpongeForgeTransformationService.java create mode 100755 neoforge/src/applaunch/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService create mode 100755 neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IDependencyLocator create mode 100755 neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator create mode 100755 neoforge/src/lang/java/org/spongepowered/forge/lang/provider/JavaPluginLanguageProvider.java create mode 100755 neoforge/src/lang/resources/META-INF/services/net.minecraftforge.forgespi.language.IModLanguageProvider create mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeLaunch.java create mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeMappingManager.java create mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/ForgePlatform.java create mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/ForgeEventBridge_Forge.java create mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/SpongeEventBridge_Forge.java create mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/command/ForgeCommandManager.java create mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/event/ForgeEventManager.java create mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/event/ListenerLookups.java create mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/event/SpongeEventBus.java create mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/inject/SpongeForgeModule.java create mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginContainer.java create mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginManager.java create mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/PluginModContainer.java create mode 100755 neoforge/src/main/java/org/spongepowered/forge/ForgeClient.java create mode 100755 neoforge/src/main/java/org/spongepowered/forge/ForgeEngine.java create mode 100755 neoforge/src/main/java/org/spongepowered/forge/ForgeServer.java create mode 100755 neoforge/src/main/java/org/spongepowered/forge/SpongeAPIMod.java create mode 100755 neoforge/src/main/java/org/spongepowered/forge/SpongeForgeMod.java create mode 100755 neoforge/src/main/java/org/spongepowered/forge/SpongeMod.java create mode 100755 neoforge/src/main/java/org/spongepowered/forge/hook/ForgeChannelHooks.java create mode 100755 neoforge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java create mode 100755 neoforge/src/main/java/org/spongepowered/forge/hook/ForgeGeneralHooks.java create mode 100755 neoforge/src/main/java/org/spongepowered/forge/hook/ForgeItemHooks.java create mode 100755 neoforge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java create mode 100755 neoforge/src/main/java/org/spongepowered/forge/world/server/ForgeWorldManager.java create mode 100755 neoforge/src/main/resource-templates/META-INF/mods.toml create mode 100755 neoforge/src/main/resources/forge.superclasschange create mode 100755 neoforge/src/main/resources/pack.mcmeta create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/api/minecraft/server/MinecraftServerMixin_Forge_API.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/EventMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/block/ChangeBlockEvent_AllMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEntityWorldEvent_PreMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEventWorldEvent_PostMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/MinecraftMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/main/MainMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/commands/CommandsMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/MinecraftForgeMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/EntityTravelToDimensionEventMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/player/PlayerEvent_PlayerChangedDimensionEventMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEventMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEvent_BreakEventMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/internal/BrandingControlMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/ForgeRegistryMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/RegistryManagerMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/network/ConnectionMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/BootstrapMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MainMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MinecraftServerMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/commands/SpreadPlayersCommandMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/level/ServerPlayerMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerGamePacketListenerImplMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerLoginPacketListenerImplMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge_Attack_Impl.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/item/ItemEntityMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/player/PlayerMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/projectile/ThrownEnderpealMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/vehicle/BoatMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/FireBlockMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/package-info.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/inventory/event/world/level/block/entity/HopperBlockEntityMixin_Inventory_Forge.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/plugin/ForgeCorePlugin.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/server/level/ServerPlayerGameModeMixin_Forge_Tracker.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/BlockMixin_Forge_Tracker.java create mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/state/BlockBehaviorMixin_Forge_Tracker.java create mode 100755 neoforge/src/mixins/resources/mixins.spongeforge.api.json create mode 100755 neoforge/src/mixins/resources/mixins.spongeforge.core.json create mode 100755 neoforge/src/mixins/resources/mixins.spongeforge.inventory.json create mode 100755 neoforge/src/mixins/resources/mixins.spongeforge.tracker.json mode change 100644 => 100755 settings.gradle.kts diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml old mode 100644 new mode 100755 index dc6fd67f2f8..1f7d1675712 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -146,6 +146,14 @@ + + + + + + + + @@ -178,6 +186,14 @@ + + + + + + + + @@ -1300,6 +1316,14 @@ + + + + + + + + @@ -1324,6 +1348,14 @@ + + + + + + + + @@ -1332,6 +1364,14 @@ + + + + + + + + @@ -1562,6 +1602,14 @@ + + + + + + + + @@ -1863,12 +1911,12 @@ - - - - - - + + + + + + @@ -1886,6 +1934,14 @@ + + + + + + + + @@ -3032,6 +3088,14 @@ + + + + + + + + @@ -3091,6 +3155,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5357,6 +5531,14 @@ + + + + + + + + @@ -5389,6 +5571,14 @@ + + + + + + + + @@ -5426,6 +5616,14 @@ + + + + + + + + @@ -5442,6 +5640,14 @@ + + + + + + + + diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts new file mode 100755 index 00000000000..571443d18de --- /dev/null +++ b/neoforge/build.gradle.kts @@ -0,0 +1,541 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar +import net.fabricmc.loom.api.LoomGradleExtensionAPI + +buildscript { + repositories { + maven("https://repo.spongepowered.org/repository/maven-public") { + name = "sponge" + } + maven("https://maven.neoforged.net/releases/") { + name = "neoforge" + } + maven("https://maven.architectury.dev/") + } +} + +plugins { + alias(libs.plugins.shadow) + id("implementation-structure") + alias(libs.plugins.blossom) + id("dev.architectury.loom") version "1.6-SNAPSHOT" +} + +val commonProject = parent!! +val transformersProject = parent!!.project(":modlauncher-transformers") +val apiVersion: String by project +val minecraftVersion: String by project +val neoForgeVersion: String by project +val recommendedVersion: String by project +val organization: String by project +val projectUrl: String by project + +val testPluginsProject: Project? = rootProject.subprojects.find { "testplugins" == it.name } + +description = "The SpongeAPI implementation for MinecraftForge" +version = spongeImpl.generatePlatformBuildVersionString(apiVersion, minecraftVersion, recommendedVersion, neoForgeVersion) + +repositories { + maven("https://repo.spongepowered.org/repository/maven-public/") { + name = "sponge" + } + maven("https://maven.neoforged.net/releases/") { + name = "neoforge" + } +} + +// SpongeForge libraries +val serviceLibrariesConfig: NamedDomainObjectProvider = configurations.register("spongeServiceLibraries") +val gameLibrariesConfig: NamedDomainObjectProvider = configurations.register("spongeGameLibraries") + +val gameManagedLibrariesConfig: NamedDomainObjectProvider = configurations.register("spongeGameManagedLibraries") + +val serviceShadedLibrariesConfig: NamedDomainObjectProvider = configurations.register("spongeServiceShadedLibraries") +val gameShadedLibrariesConfig: NamedDomainObjectProvider = configurations.register("spongeGameShadedLibraries") + +val runTaskOnlyConfig: NamedDomainObjectProvider = configurations.register("runTaskOnly") + +configurations.named("forgeRuntimeLibrary") { + extendsFrom(serviceLibrariesConfig.get()) +} + +// ModLauncher layers +val serviceLayerConfig: NamedDomainObjectProvider = configurations.register("serviceLayer") { + extendsFrom(serviceLibrariesConfig.get()) + extendsFrom(configurations.getByName("forgeDependencies")) +} +val langLayerConfig: NamedDomainObjectProvider = configurations.register("langLayer") { + extendsFrom(configurations.getByName("forgeDependencies")) +} +val gameLayerConfig: NamedDomainObjectProvider = configurations.register("gameLayer") { + extendsFrom(serviceLayerConfig.get()) + extendsFrom(langLayerConfig.get()) + extendsFrom(gameLibrariesConfig.get()) + + afterEvaluate { + extendsFrom(configurations.getByName("minecraftNamedCompile")) + } +} + +// Common source sets and configurations +val launchConfig: NamedDomainObjectProvider = commonProject.configurations.named("launch") +val accessors: NamedDomainObjectProvider = commonProject.sourceSets.named("accessors") +val launch: NamedDomainObjectProvider = commonProject.sourceSets.named("launch") +val applaunch: NamedDomainObjectProvider = commonProject.sourceSets.named("applaunch") +val mixins: NamedDomainObjectProvider = commonProject.sourceSets.named("mixins") +val main: NamedDomainObjectProvider = commonProject.sourceSets.named("main") + +// Forge source sets +val forgeMain by sourceSets.named("main") { + // implementation (compile) dependencies + spongeImpl.applyNamedDependencyOnOutput(commonProject, accessors.get(), this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(commonProject, launch.get(), this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(commonProject, applaunch.get(), this, project, this.implementationConfigurationName) + + configurations.named(implementationConfigurationName) { + extendsFrom(gameLayerConfig.get()) + } +} +val forgeLaunch by sourceSets.register("launch") { + // implementation (compile) dependencies + spongeImpl.applyNamedDependencyOnOutput(commonProject, launch.get(), this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(commonProject, applaunch.get(), this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(commonProject, main.get(), this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(project, this, forgeMain, project, forgeMain.implementationConfigurationName) + + configurations.named(implementationConfigurationName) { + extendsFrom(gameLayerConfig.get()) + } +} +val forgeAccessors by sourceSets.register("accessors") { + spongeImpl.applyNamedDependencyOnOutput(commonProject, mixins.get(), this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(project, this, forgeLaunch, project, forgeLaunch.implementationConfigurationName) + + configurations.named(implementationConfigurationName) { + extendsFrom(gameLayerConfig.get()) + } +} +val forgeMixins by sourceSets.register("mixins") { + // implementation (compile) dependencies + spongeImpl.applyNamedDependencyOnOutput(commonProject, mixins.get(), this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(commonProject, accessors.get(), this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(commonProject, launch.get(), this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(commonProject, applaunch.get(), this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(commonProject, main.get(), this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(project, forgeMain, this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(project, forgeAccessors, this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(project, forgeLaunch, this, project, this.implementationConfigurationName) + + configurations.named(implementationConfigurationName) { + extendsFrom(gameLayerConfig.get()) + } +} +val forgeLang by sourceSets.register("lang") { + configurations.named(implementationConfigurationName) { + extendsFrom(langLayerConfig.get()) + } +} +val forgeAppLaunch by sourceSets.register("applaunch") { + // implementation (compile) dependencies + spongeImpl.applyNamedDependencyOnOutput(commonProject, applaunch.get(), this, project, this.implementationConfigurationName) + spongeImpl.applyNamedDependencyOnOutput(project, this, forgeLaunch, project, forgeLaunch.implementationConfigurationName) + + configurations.named(implementationConfigurationName) { + extendsFrom(serviceLayerConfig.get()) + } +} + +configurations.configureEach { + exclude(group = "net.minecraft", module = "joined") + if (name != "minecraft") { // awful terrible hack sssh + exclude(group = "com.mojang", module = "minecraft") + } + + // Fix that can be found in Forge MDK too + resolutionStrategy { + force("net.sf.jopt-simple:jopt-simple:5.0.4") + } +} + +extensions.configure(LoomGradleExtensionAPI::class) { + silentMojangMappingsLicense() + accessWidenerPath.set(file("../src/main/resources/common.accesswidener")) + + mixin { + useLegacyMixinAp.set(false) + } + + neoForge { + + } + + mods { + named("main") { + sourceSet(forgeMixins) + sourceSet(forgeAccessors) + sourceSet(forgeLaunch) + + sourceSet(main.get(), commonProject) + sourceSet(mixins.get(), commonProject) + sourceSet(accessors.get(), commonProject) + sourceSet(launch.get(), commonProject) + + configuration(gameManagedLibrariesConfig.get()) + configuration(gameShadedLibrariesConfig.get()) + } + } + + // Arch-loom bug, skip broken union-relauncher + runs.forEach { + it.mainClass.set("net.minecraftforge.bootstrap.ForgeBootstrap") + } +} + +dependencies { + "minecraft"("com.mojang:minecraft:${minecraftVersion}") + "neoForge"("net.neoforged:neoforge:$neoForgeVersion") + "mappings"(loom.layered { + officialMojangMappings { + nameSyntheticMembers = true + } + }) + + api(project(":", configuration = "launch")) { + exclude(group = "org.spongepowered", module = "mixin") + } + implementation(project(":", configuration = "accessors")) { + exclude(group = "org.spongepowered", module = "mixin") + } + implementation(project(commonProject.path)) { + exclude(group = "org.spongepowered", module = "mixin") + } + + forgeMixins.implementationConfigurationName(project(commonProject.path)) + + val serviceLibraries = serviceLibrariesConfig.name + serviceLibraries(apiLibs.pluginSpi) + serviceLibraries(project(transformersProject.path)) + serviceLibraries(platform(apiLibs.configurate.bom)) + serviceLibraries(apiLibs.configurate.core) { + exclude(group = "org.checkerframework", module = "checker-qual") + } + serviceLibraries(apiLibs.configurate.hocon) { + exclude(group = "org.spongepowered", module = "configurate-core") + exclude(group = "org.checkerframework", module = "checker-qual") + } + serviceLibraries(libs.configurate.jackson) { + exclude(group = "org.spongepowered", module = "configurate-core") + exclude(group = "org.checkerframework", module = "checker-qual") + } + + val gameLibraries = gameLibrariesConfig.name + gameLibraries("org.spongepowered:spongeapi:$apiVersion") + gameLibraries(libs.javaxInject) + gameLibraries(platform(apiLibs.adventure.bom)) + gameLibraries(libs.adventure.serializerConfigurate4) + + val serviceShadedLibraries = serviceShadedLibrariesConfig.name + serviceShadedLibraries(project(transformersProject.path)) { isTransitive = false } + + val gameShadedLibraries = gameShadedLibrariesConfig.name + gameShadedLibraries("org.spongepowered:spongeapi:$apiVersion") { isTransitive = false } + + afterEvaluate { + spongeImpl.copyModulesExcludingProvided(serviceLibrariesConfig.get(), configurations.getByName("forgeDependencies"), serviceShadedLibrariesConfig.get()) + spongeImpl.copyModulesExcludingProvided(gameLibrariesConfig.get(), serviceLayerConfig.get(), gameManagedLibrariesConfig.get()) + } + + val runTaskOnly = runTaskOnlyConfig.name + // Arch-loom bug, fix support of MOD_CLASSES + runTaskOnly("net.minecraftforge:bootstrap-dev:2.1.3") +} + +val forgeManifest = java.manifest { + attributes( + "Specification-Title" to "SpongeForge", + "Specification-Vendor" to "SpongePowered", + "Specification-Version" to apiVersion, + "Implementation-Title" to project.name, + "Implementation-Version" to spongeImpl.generatePlatformBuildVersionString(apiVersion, minecraftVersion, recommendedVersion, neoForgeVersion), + "Implementation-Vendor" to "SpongePowered" + ) + // These two are included by most CI's + System.getenv()["GIT_COMMIT"]?.apply { attributes("Git-Commit" to this) } + System.getenv()["GIT_BRANCH"]?.apply { attributes("Git-Branch" to this) } +} + +val mixinConfigs: MutableSet = spongeImpl.mixinConfigurations + +tasks { + jar { + manifest.from(forgeManifest) + } + val forgeAppLaunchJar by registering(Jar::class) { + archiveClassifier.set("applaunch") + manifest.from(forgeManifest) + from(forgeAppLaunch.output) + } + val forgeLaunchJar by registering(Jar::class) { + archiveClassifier.set("launch") + manifest.from(forgeManifest) + from(forgeLaunch.output) + } + val forgeAccessorsJar by registering(Jar::class) { + archiveClassifier.set("accessors") + manifest.from(forgeManifest) + from(forgeAccessors.output) + } + val forgeMixinsJar by registering(Jar::class) { + archiveClassifier.set("mixins") + manifest.from(forgeManifest) + from(forgeMixins.output) + } + val forgeLangJar by registering(Jar::class) { + archiveClassifier.set("lang") + manifest { + from(forgeManifest) + attributes("FMLModType" to "LANGPROVIDER") + } + from(forgeLang.output) + } + + val forgeServicesDevJar by registering(Jar::class) { + archiveClassifier.set("services") + manifest.from(forgeManifest) + + from(commonProject.sourceSets.named("applaunch").map { it.output }) + from(forgeAppLaunch.output) + + duplicatesStrategy = DuplicatesStrategy.WARN + } + + afterEvaluate { + withType(net.fabricmc.loom.task.AbstractRunTask::class) { + // Default classpath is a mess, we better start a new one from scratch + classpath = files( + configurations.getByName("forgeRuntimeLibrary"), + forgeServicesDevJar, forgeLangJar, runTaskOnlyConfig + ) + + testPluginsProject?.also { + val testPluginsOutput = it.sourceSets.getByName("main").output + val dirs: MutableList = mutableListOf() + dirs.add(testPluginsOutput.resourcesDir!!) + dirs.addAll(testPluginsOutput.classesDirs) + environment["SPONGE_PLUGINS"] = dirs.joinToString("&") + + dependsOn(it.tasks.classes) + } + + argumentProviders += CommandLineArgumentProvider { + mixinConfigs.asSequence() + .flatMap { sequenceOf("--mixin.config", it) } + .toList() + } + + // jvmArguments.add("-Dbsl.debug=true") // Uncomment to debug bootstrap classpath + + sourceSets.forEach { + dependsOn(it.classesTaskName) + } + } + } + + val installerResources = project.layout.buildDirectory.dir("generated/resources/installer") + forgeAppLaunch.resources.srcDir(installerResources) + + val emitDependencies by registering(org.spongepowered.gradle.impl.OutputDependenciesToJson::class) { + group = "sponge" + this.dependencies("main", gameManagedLibrariesConfig) + this.excludedDependencies(gameShadedLibrariesConfig) + + outputFile.set(installerResources.map { it.file("org/spongepowered/forge/applaunch/loading/moddiscovery/libraries.json") }) + } + named(forgeAppLaunch.processResourcesTaskName).configure { + dependsOn(emitDependencies) + } + + val forgeServicesShadowJar by register("servicesShadowJar", ShadowJar::class) { + group = "shadow" + archiveClassifier.set("services") + + mergeServiceFiles() + configurations = listOf(serviceShadedLibrariesConfig.get()) + exclude("META-INF/INDEX.LIST", "META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA", "module-info.class") + + manifest { + attributes("Automatic-Module-Name" to "spongeforge.services") + attributes("Multi-Release" to true) + from(forgeManifest) + } + + from(commonProject.sourceSets.named("applaunch").map { it.output }) + from(forgeAppLaunch.output) + + // Make sure to relocate access widener so that we don't conflict with other coremods + relocate("net.fabricmc.accesswidener", "org.spongepowered.forge.libs.accesswidener") + } + + shadowJar { + group = "shadow" + archiveClassifier.set("mod") + + mergeServiceFiles() + configurations = listOf(gameShadedLibrariesConfig.get()) + + manifest { + attributes( + "Access-Widener" to "common.accesswidener", + "Superclass-Transformer" to "common.superclasschange,forge.superclasschange", + "MixinConfigs" to mixinConfigs.joinToString(",") + ) + from(forgeManifest) + } + + from(commonProject.sourceSets.main.map { it.output }) + from(commonProject.sourceSets.named("mixins").map {it.output }) + from(commonProject.sourceSets.named("accessors").map {it.output }) + from(commonProject.sourceSets.named("launch").map {it.output }) + + from(forgeLaunch.output) + from(forgeAccessors.output) + from(forgeMixins.output) + } + + val universalJar = register("universalJar", Jar::class) { + group = "build" + archiveClassifier.set("universal") + + manifest.from(forgeServicesShadowJar.manifest) + + from(forgeServicesShadowJar.archiveFile.map { zipTree(it) }) + + into("jars") { + from(shadowJar) + rename("spongeforge-(.*)-mod.jar", "spongeforge-mod.jar") + + from(forgeLangJar) + rename("spongeforge-(.*)-lang.jar", "spongeforge-lang.jar") + } + } + + assemble { + dependsOn(universalJar) + } +} + +sourceSets { + main { + blossom.resources { + property("version", project.provider { project.version.toString() }) + property("description", project.description.toString()) + } + } +} + +afterEvaluate { + sourceSets.configureEach { + // Don't apply Mixin AP + configurations.named(annotationProcessorConfigurationName) { + exclude(group = "org.spongepowered", module = "mixin") + exclude(group = "net.fabricmc", module = "fabric-mixin-compile-extensions") + } + // And don't pass AP parameters + tasks.named(compileJavaTaskName, JavaCompile::class) { + val mixinApArgs = setOf("outRefMapFile", "defaultObfuscationEnv", "outMapFileNamedIntermediary", "inMapFileNamedIntermediary") + options.compilerArgs.removeIf { mixinApArgs.any { mixin -> it.contains(mixin)} } + } + } +} + +indraSpotlessLicenser { + licenseHeaderFile(rootProject.file("HEADER.txt")) + + property("name", "Sponge") + property("organization", organization) + property("url", projectUrl) +} + +publishing { + publications { + register("sponge", MavenPublication::class) { + artifact(tasks["universalJar"]) + + artifact(tasks["jar"]) + artifact(tasks["sourcesJar"]) + + artifact(tasks["forgeMixinsJar"]) + artifact(tasks["mixinsSourcesJar"]) + + artifact(tasks["forgeAccessorsJar"]) + artifact(tasks["accessorsSourcesJar"]) + + artifact(tasks["forgeLaunchJar"]) + artifact(tasks["launchSourcesJar"]) + + artifact(tasks["forgeAppLaunchJar"]) + artifact(tasks["applaunchSourcesJar"]) + + pom { + artifactId = project.name.lowercase() + this.name.set(project.name) + this.description.set(project.description) + this.url.set(projectUrl) + + licenses { + license { + this.name.set("MIT") + this.url.set("https://opensource.org/licenses/MIT") + } + } + scm { + connection.set("scm:git:git://github.com/SpongePowered/Sponge.git") + developerConnection.set("scm:git:ssh://github.com/SpongePowered/Sponge.git") + this.url.set(projectUrl) + } + } + } + } +} + +tasks.register("printConfigsHierarchy") { + group = "debug" + doLast { + configurations.forEach { conf: Configuration -> + val seen = mutableSetOf() + println("Parents of ${conf.name}:") + printParents(conf, "", seen) + } + } +} + +fun printParents(conf: Configuration, indent: String, seen: MutableSet) { + for (parent in conf.extendsFrom) { + if (parent in seen) { + continue + } + seen.add(parent) + println("$indent - ${parent.name}") + printParents(parent, indent + " ", seen) + } +} + +tasks.register("printConfigsResolution") { + group = "debug" + doLast { + configurations.forEach { conf: Configuration -> + println() + println("Artifacts of ${conf.name}:") + if (conf.isCanBeResolved) { + try { + conf.forEach { + println(it) + } + } catch (e: Exception) { + println("error") + } + } else { + println("not resolved") + } + } + } +} diff --git a/neoforge/gradle.properties b/neoforge/gradle.properties new file mode 100755 index 00000000000..1c271bdaa7f --- /dev/null +++ b/neoforge/gradle.properties @@ -0,0 +1,8 @@ +name=SpongeNeoForge +implementation=NeoForge +description=The SpongeAPI implementation for MinecraftNeoForge + +neoForgeVersion=21.1.1 +loom.platform=neoforge +fabric.loom.dontRemap=true +mixinConfigs=mixins.spongeforge.accessors.json,mixins.spongeforge.api.json,mixins.spongeforge.inventory.json,mixins.spongeforge.core.json,mixins.spongeforge.tracker.json \ No newline at end of file diff --git a/neoforge/src/accessors/resources/mixins.spongeforge.accessors.json b/neoforge/src/accessors/resources/mixins.spongeforge.accessors.json new file mode 100755 index 00000000000..bf8a8bda19f --- /dev/null +++ b/neoforge/src/accessors/resources/mixins.spongeforge.accessors.json @@ -0,0 +1,7 @@ +{ + "required": true, + "parent": "mixins.sponge.parent.json", + "package": "org.spongepowered.forge.accessor", + "mixins": [ + ] +} \ No newline at end of file diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginDependencyConfigurable.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginDependencyConfigurable.java new file mode 100755 index 00000000000..a52ee64b10d --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginDependencyConfigurable.java @@ -0,0 +1,77 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.metadata; + +import net.neoforged.neoforgespi.language.IConfigurable; +import net.neoforged.neoforgespi.language.IModInfo; + +import org.spongepowered.plugin.metadata.PluginMetadata; +import org.spongepowered.plugin.metadata.model.PluginDependency; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +// ModVersion +public final class PluginDependencyConfigurable implements IConfigurable { + + private final PluginMetadata metadata; + private final PluginDependency dependency; + + public PluginDependencyConfigurable(final PluginMetadata metadata, final PluginDependency dependency) { + this.metadata = metadata; + this.dependency = dependency; + } + + @SuppressWarnings("unchecked") + @Override + public Optional getConfigElement(final String... key) { + if (key.length != 1) { + return Optional.empty(); + } + + return switch (key[0]) { + case "modId" -> (Optional) Optional.of(this.dependency.id()); + case "mandatory" -> (Optional) Optional.of(!this.dependency.optional()); + case "versionRange" -> (Optional) Optional.of(this.dependency.version().toString()); + case "ordering" -> (Optional) Optional.of(this.loadToOrdering(this.dependency.loadOrder()).toString()); + case "side" -> (Optional) Optional.of(IModInfo.DependencySide.BOTH.toString()); + default -> Optional.empty(); + }; + } + + @Override + public List getConfigList(final String... key) { + return Collections.emptyList(); + } + + private IModInfo.Ordering loadToOrdering(final PluginDependency.LoadOrder order) { + if (order == PluginDependency.LoadOrder.AFTER) { + return IModInfo.Ordering.AFTER; + } + + return IModInfo.Ordering.NONE; + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginFileConfigurable.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginFileConfigurable.java new file mode 100755 index 00000000000..acc6cbd7001 --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginFileConfigurable.java @@ -0,0 +1,140 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.metadata; + +import net.neoforged.neoforgespi.language.IConfigurable; +import org.spongepowered.plugin.metadata.PluginMetadata; +import org.spongepowered.plugin.metadata.builtin.MetadataContainer; +import org.spongepowered.plugin.metadata.model.PluginDependency; + +import java.util.*; + +// ModFileInfo +public final class PluginFileConfigurable implements IConfigurable { + + private final MetadataContainer container; + + public PluginFileConfigurable(final MetadataContainer container) { + this.container = container; + } + + @SuppressWarnings("unchecked") + @Override + public Optional getConfigElement(final String... key) { + if (key.length < 1) { + return Optional.empty(); + } + + final String query = key[0]; + if (key.length != this.requiredConfigElements(query)) { + return Optional.empty(); + } + + if ("modLoader".equals(query)) { + return (Optional) Optional.of(this.container.loader().name()); + } + + if ("loaderVersion".equals(query)) { + return (Optional) Optional.of(this.container.loader().version().toString()); + } + + if ("license".equals(query)) { + return (Optional) Optional.of(this.container.license()); + } + + if (key.length == 2) { + final String plugin = key[1]; + final PluginMetadata metadata = this.container.metadata(plugin).orElse(null); + if (metadata == null) { + return Optional.empty(); + } + + if ("modproperties".equals(query)) { + return (Optional) Optional.of(metadata.properties()); + } + } + + return Optional.empty(); + } + + @Override + public List getConfigList(final String... key) { + if (key.length < 1) { + return Collections.emptyList(); + } + + final String query = key[0]; + if (key.length != this.requiredConfigElements(query)) { + return Collections.emptyList(); + } + + if ("mods".equals(query)) { + final Set metadataById = this.container.metadata(); + if (metadataById.isEmpty()) { + return Collections.emptyList(); + } + + final List metadataConfigurables = new ArrayList<>(); + metadataById.forEach((metadata) -> metadataConfigurables.add(new PluginMetadataConfigurable(metadata))); + return metadataConfigurables; + } + + if (key.length != 2) { + return Collections.emptyList(); + } + + final String plugin = key[1]; + final PluginMetadata metadata = this.container.metadata(plugin).orElse(null); + if (metadata == null) { + return Collections.emptyList(); + } + + if ("dependencies".equals(query)) { + + // TODO Should we inject a dependency on SpongeForge? + final Set dependencies = metadata.dependencies(); + if (dependencies.isEmpty()) { + return Collections.emptyList(); + } + + final List depConfigurables = new ArrayList<>(); + for (final PluginDependency dependency : dependencies) { + depConfigurables.add(new PluginDependencyConfigurable(metadata, dependency)); + } + + return depConfigurables; + } + + return Collections.emptyList(); + } + + private int requiredConfigElements(final String query) { + if ("dependencies".equals(query) || "modproperties".equals(query)) { + return 2; + } + + return 1; + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataConfigurable.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataConfigurable.java new file mode 100755 index 00000000000..98567a39639 --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataConfigurable.java @@ -0,0 +1,65 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.metadata; + +import net.neoforged.neoforgespi.language.IConfigurable; + +import org.spongepowered.plugin.metadata.PluginMetadata; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +// ModInfo +public final class PluginMetadataConfigurable implements IConfigurable { + + private final PluginMetadata metadata; + + public PluginMetadataConfigurable(final PluginMetadata metadata) { + this.metadata = metadata; + } + + @SuppressWarnings("unchecked") + @Override + public Optional getConfigElement(final String... key) { + if (key.length != 1) { + return Optional.empty(); + } + + return switch (key[0]) { + case "modId" -> Optional.of((T) this.metadata.id()); + case "version" -> Optional.of((T) this.metadata.version().toString()); + case "displayName" -> (Optional) this.metadata.name(); + case "description" -> (Optional) this.metadata.description(); + case "displayTest" -> Optional.of((T) "IGNORE_SERVER_VERSION"); + default -> Optional.empty(); + }; + } + + @Override + public List getConfigList(final String... key) { + return Collections.emptyList(); + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataUtils.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataUtils.java new file mode 100755 index 00000000000..3a40bca1feb --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataUtils.java @@ -0,0 +1,83 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.metadata; + +import net.neoforged.fml.loading.moddiscovery.ModInfo; +import net.neoforged.neoforgespi.language.IModInfo; + +import org.spongepowered.plugin.metadata.PluginMetadata; +import org.spongepowered.plugin.metadata.builtin.StandardPluginMetadata; +import org.spongepowered.plugin.metadata.builtin.model.StandardPluginContributor; +import org.spongepowered.plugin.metadata.builtin.model.StandardPluginDependency; +import org.spongepowered.plugin.metadata.builtin.model.StandardPluginLinks; +import org.spongepowered.plugin.metadata.model.PluginDependency; + +import java.util.ArrayList; +import java.util.List; + +/** + * ModInfo cannot be mixed into as it is on the app class loader so this somewhat hacky util class will do... + */ +public final class PluginMetadataUtils { + + public static PluginMetadata modToPlugin(final ModInfo info) { + final StandardPluginMetadata.Builder builder = StandardPluginMetadata.builder(); + builder + .id(info.getModId()) + .name(info.getDisplayName()) + .version(info.getVersion().toString()) + .description(info.getDescription()) + .entrypoint("unknown") // TODO Map main class to mod id + .addContributor(StandardPluginContributor.builder() + .name(info.getConfigElement("authors").orElse("unknown").toString()) + .build()); + builder.links(StandardPluginLinks.builder().issues(info.getOwningFile().getIssueURL()).build()); + + final List dependencies = new ArrayList<>(); + for (final IModInfo.ModVersion dependency : info.getDependencies()) { + final StandardPluginDependency.Builder depBuilder = StandardPluginDependency.builder(); + depBuilder + .id(dependency.getModId()) + .loadOrder(PluginMetadataUtils.orderingToLoad(dependency.getOrdering())) + .version(dependency.getVersionRange().toString()) + ; + + dependencies.add(depBuilder.build()); + } + + if (!dependencies.isEmpty()) { + builder.dependencies(dependencies); + } + + return builder.build(); + } + + private static PluginDependency.LoadOrder orderingToLoad(final IModInfo.Ordering ordering) { + if (ordering == IModInfo.Ordering.AFTER) { + return PluginDependency.LoadOrder.AFTER; + } + return PluginDependency.LoadOrder.UNDEFINED; + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/ModFileParsers.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/ModFileParsers.java new file mode 100755 index 00000000000..fa4d4c3a8c8 --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/ModFileParsers.java @@ -0,0 +1,112 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.moddiscovery; + +import cpw.mods.jarhandling.SecureJar; + +import net.neoforged.fml.loading.moddiscovery.ModFile; +import net.neoforged.fml.loading.moddiscovery.ModFileInfo; +import net.neoforged.fml.loading.moddiscovery.ModJarMetadata; +import net.neoforged.neoforgespi.language.IModFileInfo; +import net.neoforged.neoforgespi.locating.*; + +import org.spongepowered.common.applaunch.AppLaunch; +import org.spongepowered.common.applaunch.plugin.PluginPlatformConstants; +import org.spongepowered.forge.applaunch.loading.metadata.PluginFileConfigurable; +import org.spongepowered.plugin.metadata.builtin.MetadataContainer; +import org.spongepowered.plugin.metadata.builtin.MetadataParser; + +import java.io.Reader; +import java.lang.reflect.Constructor; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +public final class ModFileParsers { + private static Constructor modJarMetadataConstructor; + + static { + try { + ModFileParsers.modJarMetadataConstructor = ModJarMetadata.class.getDeclaredConstructor(); + ModFileParsers.modJarMetadataConstructor.setAccessible(true); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + + public static IModFileInfo parsePluginMetadata(final IModFile iModFile) { + final ModFile modFile = (ModFile) iModFile; + AppLaunch.logger().debug("Considering plugin file candidate {}", modFile.getFilePath()); + + final Path metadataFile = modFile.findResource(PluginPlatformConstants.METADATA_FILE_LOCATION); + if (Files.notExists(metadataFile)) { + AppLaunch.logger().debug("Plugin file '{}' is missing a 'sponge_plugins.json' metadata file in META-INF", modFile); + return null; + } + + try { + final MetadataContainer container; + try (final Reader reader = Files.newBufferedReader(metadataFile, StandardCharsets.UTF_8)) { + container = MetadataParser.read(reader); + } + + final PluginFileConfigurable config = new PluginFileConfigurable(container); + return new ModFileInfo(modFile, config, (info) -> {}, List.of()); + } catch (final Exception e) { + AppLaunch.logger().warn("Could not read metadata for plugin file '{}'", modFile, e); + return null; + } + } + + private static ModJarMetadata newModJarMetadata() { + try { + return modJarMetadataConstructor.newInstance(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static ModFile newPluginInstance(final IModFileCandidateLocator locator, final Path... path) { + ModJarMetadata mjm = newModJarMetadata(); + ModFileInfoParser parser = ModFileParsers::parsePluginMetadata; + + ModFile modFile = new ModFile(SecureJar.from(path), parser, ModFileDiscoveryAttributes.DEFAULT.withLocator(locator)); + mjm.setModFile(modFile); + return modFile; + } + + public static ModFile newPluginInstance(final IDependencyLocator locator, final Path... path) { + ModJarMetadata mjm = newModJarMetadata(); + ModFileInfoParser parser = ModFileParsers::parsePluginMetadata; + + ModFile modFile = new ModFile(SecureJar.from(path), parser, ModFileDiscoveryAttributes.DEFAULT.withDependencyLocator(locator)); + mjm.setModFile(modFile); + return modFile; + } + + private ModFileParsers() { + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeDependencyLocator.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeDependencyLocator.java new file mode 100755 index 00000000000..2757a0fde22 --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeDependencyLocator.java @@ -0,0 +1,82 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.moddiscovery; + +import cpw.mods.modlauncher.Environment; +import cpw.mods.modlauncher.Launcher; + +import net.neoforged.fml.loading.FMLEnvironment; +import net.neoforged.fml.loading.moddiscovery.ModFile; +import net.neoforged.neoforgespi.locating.IDependencyLocator; +import net.neoforged.neoforgespi.locating.IDiscoveryPipeline; +import net.neoforged.neoforgespi.locating.IModFile; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.spongepowered.forge.applaunch.loading.moddiscovery.library.LibraryManager; +import org.spongepowered.forge.applaunch.transformation.SpongeForgeTransformationService; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +// works with ForgeProductionBootstrap to make this whole thing go +public class SpongeForgeDependencyLocator implements IDependencyLocator { + private static final Logger LOGGER = LogManager.getLogger(); + private final List modFiles = new ArrayList<>(); + + final Environment env = Launcher.INSTANCE.environment(); + private LibraryManager libraryManager = new LibraryManager( + env.getProperty(SpongeForgeTransformationService.Keys.CHECK_LIBRARY_HASHES.get()).orElse(true), + env.getProperty(SpongeForgeTransformationService.Keys.LIBRARIES_DIRECTORY.get()) + .orElseThrow(() -> new IllegalStateException("no libraries available")), + SpongeForgeModLocator.class.getResource("libraries.json")); + + @Override + public void scanMods(List loadedMods, IDiscoveryPipeline pipeline) { + // Add Sponge-specific libraries + if (FMLEnvironment.production) { + try { + this.libraryManager.validate(); + } catch (final Exception ex) { + throw new RuntimeException("Failed to download and validate Sponge libraries", ex); + } + this.libraryManager.finishedProcessing(); + + for (final LibraryManager.Library library : this.libraryManager.getAll().values()) { + final Path path = library.getFile(); + SpongeForgeDependencyLocator.LOGGER.debug("Proposing jar {} as a game library", path); + ModFile mod = ModFileParsers.newPluginInstance(this, path); + modFiles.add(mod); + } + } + } + + public List getModFiles() { + return modFiles; + } + +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeModLocator.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeModLocator.java new file mode 100755 index 00000000000..c03d28ac3a0 --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeModLocator.java @@ -0,0 +1,93 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.moddiscovery; + +import com.google.common.collect.ImmutableMap; +import cpw.mods.modlauncher.Environment; +import cpw.mods.modlauncher.Launcher; + +import net.neoforged.fml.javafmlmod.FMLJavaModLanguageProvider; +import net.neoforged.neoforgespi.ILaunchContext; +import net.neoforged.neoforgespi.locating.IDiscoveryPipeline; +import net.neoforged.neoforgespi.locating.IModFile; +import net.neoforged.neoforgespi.locating.IModFileCandidateLocator; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.spongepowered.forge.applaunch.plugin.ForgePluginPlatform; + +import java.net.URI; +import java.net.URL; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +public final class SpongeForgeModLocator extends FMLJavaModLanguageProvider implements IModFileCandidateLocator { + private static final Logger LOGGER = LogManager.getLogger(); + private List modFiles = new ArrayList<>(); + + @Override + public void findCandidates(ILaunchContext context, IDiscoveryPipeline pipeline) { + try { + URL rootJar = SpongeForgeModLocator.class.getProtectionDomain().getCodeSource().getLocation(); + FileSystem fs = FileSystems.getFileSystem(rootJar.toURI()); // FML has already opened a file system for this jar + modFiles = Files.list(fs.getPath("jars")) + .filter(path -> path.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".jar")) + .map(path -> { + try { + URI jij = new URI("jij:" + path.toAbsolutePath().toUri().getRawSchemeSpecificPart()).normalize(); + final Map env = ImmutableMap.of("packagePath", path); + FileSystem jijFS = FileSystems.newFileSystem(jij, env); + return jijFS.getPath("/"); // root of the archive to load + } catch (Exception e) { + return null; + } + }).filter(path -> path != null).map(this::createMod).toList(); + } catch (Exception e) { + LOGGER.error("Failed to scan mod candidates", e); + } + } + + private IModFile createMod(Path path) { + return ModFileParsers.newPluginInstance(this, path); + } + + @Override + public String name() { + return "spongeneoforge"; + } + + //@Override + public void initArguments(Map arguments) { + final Environment env = Launcher.INSTANCE.environment(); + ForgePluginPlatform.bootstrap(env); + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/AsyncUtils.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/AsyncUtils.java new file mode 100755 index 00000000000..61f212cf090 --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/AsyncUtils.java @@ -0,0 +1,52 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.moddiscovery.library; + +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; + +final class AsyncUtils { + + private AsyncUtils() { + } + + static CompletableFuture asyncFailableFuture(final Callable action, final Executor executor) { + final CompletableFuture future = new CompletableFuture<>(); + executor.execute(() -> { + try { + future.complete(action.call()); + } catch (final Exception ex) { + future.completeExceptionally(ex); + } + }); + return future; + } + + @SuppressWarnings("unchecked") + static R sneakyThrow(final Throwable original) throws T { + throw (T) original; + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/InstallerUtils.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/InstallerUtils.java new file mode 100755 index 00000000000..2c36eeff408 --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/InstallerUtils.java @@ -0,0 +1,169 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.moddiscovery.library; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; +import java.nio.channels.ReadableByteChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.security.DigestInputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +final class InstallerUtils { + + private static final Logger LOGGER = LogManager.getLogger(); + // From http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java + private static final char[] hexArray = "0123456789abcdef".toCharArray(); + + private InstallerUtils() { + } + + public static String toHexString(final byte[] bytes) { + final char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + final int v = bytes[j] & 0xFF; + hexChars[j * 2] = InstallerUtils.hexArray[v >>> 4]; + hexChars[j * 2 + 1] = InstallerUtils.hexArray[v & 0x0F]; + } + return new String(hexChars); + } + + public static boolean validateSha1(final String expectedHash, final Path path) throws IOException { + try (final InputStream is = Files.newInputStream(path)) { + return InstallerUtils.validateSha1(expectedHash, is); + } + } + + public static boolean validateSha1(final String expectedHash, final InputStream stream) throws IOException { + final MessageDigest digest; + try { + digest = MessageDigest.getInstance("SHA-1"); + } catch (final NoSuchAlgorithmException ex) { + throw new AssertionError(ex); // Guaranteed present by MessageDigest spec + } + + final byte[] buf = new byte[4096]; + int read; + + while ((read = stream.read(buf)) != -1) { + digest.update(buf,0, read); + } + + return expectedHash.equals(InstallerUtils.toHexString(digest.digest())); + } + + /** + * Downloads a file. + * + * @param url The file URL + * @param path The local path + * @throws IOException If there is a problem while downloading the file + */ + public static void download(final URL url, final Path path, final boolean requiresRequest) throws IOException { + Files.createDirectories(path.getParent()); + + final String name = path.getFileName().toString(); + + InstallerUtils.LOGGER.info("Downloading {}. This may take a while...", name); + InstallerUtils.LOGGER.info("URL -> <{}>", url); + + if (!requiresRequest) { + try (final ReadableByteChannel in = Channels.newChannel(url.openStream()); final FileChannel out = FileChannel.open(path, + StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) { + out.transferFrom(in, 0, Long.MAX_VALUE); + } + } else { + final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("User-Agent", "Sponge-Downloader"); + + connection.connect(); + + try (final ReadableByteChannel in = Channels.newChannel(connection.getInputStream()); final FileChannel out = FileChannel.open(path, + StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) { + out.transferFrom(in, 0, Long.MAX_VALUE); + } + } + } + + /** + * Downloads a file and verify its digest. + * + * @param url The file URL + * @param path The local path + * @param expected The SHA-1 expected digest + * @throws IOException If there is a problem while downloading the file + */ + public static void downloadCheckHash(final URL url, final Path path, final MessageDigest digest, final String expected, + final boolean requiresRequest) throws IOException { + Files.createDirectories(path.getParent()); + + final String name = path.getFileName().toString(); + + InstallerUtils.LOGGER.info("Downloading {}. This may take a while...", name); + InstallerUtils.LOGGER.debug("URL -> <{}>", url); + + if (!requiresRequest) { + // Pipe the download stream into the file and compute the hash + try (final DigestInputStream stream = new DigestInputStream(url.openStream(), digest); final ReadableByteChannel in = Channels + .newChannel(stream); final FileChannel out = FileChannel.open(path, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) { + out.transferFrom(in, 0, Long.MAX_VALUE); + } + } else { + final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("User-Agent", "Sponge-Downloader"); + + connection.connect(); + + // Pipe the download stream into the file and compute the hash + try (final DigestInputStream stream = new DigestInputStream(connection.getInputStream(), digest); final ReadableByteChannel in = Channels + .newChannel(stream); final FileChannel out = FileChannel.open(path, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) { + out.transferFrom(in, 0, Long.MAX_VALUE); + } + } + + final String fileSha1 = InstallerUtils.toHexString(digest.digest()); + + if (expected.equalsIgnoreCase(fileSha1)) { + InstallerUtils.LOGGER.info("Successfully downloaded {} and verified checksum!", name); + } else { + Files.delete(path); + throw new IOException(String.format("Checksum verification failed: Expected '%s', got '%s'.", expected, fileSha1)); + } + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/LibraryManager.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/LibraryManager.java new file mode 100755 index 00000000000..868427dce7b --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/LibraryManager.java @@ -0,0 +1,246 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.moddiscovery.library; + +import com.google.gson.Gson; +import com.google.gson.stream.JsonReader; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.spongepowered.forge.applaunch.loading.moddiscovery.library.model.sponge.Libraries; +import org.spongepowered.forge.applaunch.loading.moddiscovery.library.model.sponge.SonatypeResponse; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; +import java.util.*; +import java.util.concurrent.*; + +// copied from SV +public final class LibraryManager { + + public static final String SPONGE_NEXUS_DOWNLOAD_URL = "https://repo.spongepowered.org/service/rest/v1/search/assets?md5=%s&maven" + + ".groupId=%s&maven.artifactId=%s&maven.baseVersion=%s&maven.extension=jar"; + private static final Logger LOGGER = LogManager.getLogger(); + + private final boolean checkLibraryHashes; + private final Path rootDirectory; + private final URL librariesUrl; + private final Map libraries; + private final ExecutorService preparationWorker; + + public LibraryManager(final boolean checkLibraryHashes, final Path rootDirectory, final URL librariesUrl) { + this.checkLibraryHashes = checkLibraryHashes; + this.rootDirectory = Objects.requireNonNull(rootDirectory, "rootDirectory"); + this.librariesUrl = Objects.requireNonNull(librariesUrl, "librariesUrl"); + + this.libraries = new LinkedHashMap<>(); + final int availableCpus = Runtime.getRuntime().availableProcessors(); + // We'll be performing mostly IO-blocking operations, so more threads will help us for now + // It might make sense to make this overridable eventually + this.preparationWorker = new ThreadPoolExecutor( + Math.min(Math.max(4, availableCpus * 2), 64), Integer.MAX_VALUE, + 60L, TimeUnit.SECONDS, + new LinkedBlockingQueue<>() // this is the number of tasks allowed to be waiting before the pool will spawn off a new thread (unbounded) + ); + } + + public Path getRootDirectory() { + return this.rootDirectory; + } + + public Map getAll() { + return Collections.unmodifiableMap(this.libraries); + } + + protected void addLibrary(final Library library) { + this.libraries.put(library.getName(), library); + } + + public void validate() throws Exception { + LibraryManager.LOGGER.info("Scanning and verifying libraries in '{}'. Please wait, this may take a moment...", this.rootDirectory); + + final Gson gson = new Gson(); + + final Libraries dependencies; + try (final JsonReader reader = new JsonReader(new InputStreamReader(this.librariesUrl.openStream(), StandardCharsets.UTF_8))) { + dependencies = gson.fromJson(reader, Libraries.class); + } + + final Set downloadedDeps = ConcurrentHashMap.newKeySet(); + final List> operations = new ArrayList<>(dependencies.dependencies.size()); + final Set failures = ConcurrentHashMap.newKeySet(); + + for (final Libraries.Dependency dependency : dependencies.dependencies.get("main")) { // todo: evaluate dep sections for forge + operations.add(AsyncUtils.asyncFailableFuture(() -> { + final String groupPath = dependency.group.replace(".", "/"); + final Path depDirectory = + this.rootDirectory.resolve(groupPath).resolve(dependency.module).resolve(dependency.version); + Files.createDirectories(depDirectory); + final Path depFile = depDirectory.resolve(dependency.module + "-" + dependency.version + ".jar"); + final MessageDigest md5 = MessageDigest.getInstance("MD5"); + + final boolean checkHashes = this.checkLibraryHashes; + + if (Files.exists(depFile)) { + if (!checkHashes) { + LibraryManager.LOGGER.info("Detected existing '{}', skipping hash checks...", depFile); + downloadedDeps.add(new Library(dependency.group + "-" + dependency.module, depFile)); + return null; + } + + // Pipe the download stream into the file and compute the SHA-1 + final byte[] bytes = Files.readAllBytes(depFile); + final String fileMd5 = InstallerUtils.toHexString(md5.digest(bytes)); + + if (dependency.md5.equals(fileMd5)) { + LibraryManager.LOGGER.debug("'{}' verified!", depFile); + } else { + LibraryManager.LOGGER.error("Checksum verification failed: Expected {}, {}. Deleting cached '{}'...", + dependency.md5, fileMd5, depFile); + Files.delete(depFile); + + final SonatypeResponse response = this.getResponseFor(gson, dependency); + + if (response.items.isEmpty()) { + failures.add("No data received from '" + new URL(String.format(LibraryManager.SPONGE_NEXUS_DOWNLOAD_URL, + dependency.md5, dependency.group, + dependency.module, dependency.version)) + "'!"); + return null; + } + final SonatypeResponse.Item item = response.items.get(0); + final URL url = item.downloadUrl; + + InstallerUtils.downloadCheckHash(url, depFile, md5, item.checksum.md5, true); + } + } else { + final SonatypeResponse response = this.getResponseFor(gson, dependency); + + if (response.items.isEmpty()) { + failures.add("No data received from '" + new URL(String.format(LibraryManager.SPONGE_NEXUS_DOWNLOAD_URL, + dependency.md5, dependency.group, + dependency.module, dependency.version)) + "'!"); + return null; + } + + final SonatypeResponse.Item item = response.items.get(0); + final URL url = item.downloadUrl; + + if (checkHashes) { + InstallerUtils.downloadCheckHash(url, depFile, md5, item.checksum.md5, true); + } else { + InstallerUtils.download(url, depFile, true); + } + } + + downloadedDeps.add(new Library(dependency.group + "-" + dependency.module, depFile)); + return null; + }, this.preparationWorker)); + } + + + CompletableFuture.allOf(operations.toArray(new CompletableFuture[0])).handle((result, err) -> { + if (err != null) { + failures.add(err.getMessage()); + LibraryManager.LOGGER.error("Failed to download library", err); + } + return result; + }).join(); + + if (!failures.isEmpty()) { + LibraryManager.LOGGER.error("Failed to download some libraries:"); + for (final String message : failures) { + LibraryManager.LOGGER.error(message); + } + System.exit(-1); + } + + for (final Library library : downloadedDeps) { + this.libraries.put(library.getName(), library); + } + } + + private SonatypeResponse getResponseFor(final Gson gson, final Libraries.Dependency dependency) throws IOException { + final URL requestUrl = new URL(String.format(LibraryManager.SPONGE_NEXUS_DOWNLOAD_URL, dependency.md5, dependency.group, + dependency.module, dependency.version)); + + final HttpURLConnection connection = (HttpURLConnection) requestUrl.openConnection(); + connection.setRequestMethod("GET"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("User-Agent", "Sponge-Downloader"); + + connection.connect(); + + try (final JsonReader reader = new JsonReader(new InputStreamReader(connection.getInputStream()))) { + return gson.fromJson(reader, SonatypeResponse.class); + } + } + + public ExecutorService preparationWorker() { + return this.preparationWorker; + } + + public void finishedProcessing() { + if (this.preparationWorker.isTerminated()) { + return; + } + + this.preparationWorker.shutdown(); + boolean successful; + try { + successful = this.preparationWorker.awaitTermination(10L, TimeUnit.SECONDS); + } catch (final InterruptedException e) { + successful = false; + } + + if (!successful) { + LibraryManager.LOGGER.warn("Failed to shut down library preparation pool in 10 seconds, forcing shutdown now."); + this.preparationWorker.shutdownNow(); + } + } + + public static class Library { + + private final String name; + private final Path file; + + public Library(final String name, final Path file) { + this.name = name; + this.file = file; + } + + public String getName() { + return this.name; + } + + public Path getFile() { + return this.file; + } + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/Libraries.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/Libraries.java new file mode 100755 index 00000000000..f4fbc73b538 --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/Libraries.java @@ -0,0 +1,57 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.moddiscovery.library.model.sponge; + +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public final class Libraries { + + public Map> dependencies; + + public static final class Dependency { + + public String group, module, version, md5; + + @Override + public int hashCode() { + return Objects.hash(this.group, this.module); + } + + @Override + public boolean equals(final Object o) { + if (this == o) { + return true; + } + if (o == null || this.getClass() != o.getClass()) { + return false; + } + final Dependency that = (Dependency) o; + return this.group.equals(that.group) && + this.module.equals(that.module); + } + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/SonatypeResponse.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/SonatypeResponse.java new file mode 100755 index 00000000000..8ea4e7ce392 --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/SonatypeResponse.java @@ -0,0 +1,46 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.moddiscovery.library.model.sponge; + +import java.net.URL; +import java.util.List; + +public final class SonatypeResponse { + + public List items; + public String continuationToken; + + public static final class Item { + + public URL downloadUrl; + public String path, id, repository, format; + public Checksum checksum; + } + + public static final class Checksum { + + public String sha1, md5; + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/EnvironmentPluginLocator.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/EnvironmentPluginLocator.java new file mode 100755 index 00000000000..02b0b181508 --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/EnvironmentPluginLocator.java @@ -0,0 +1,97 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.moddiscovery.locator; + +import net.neoforged.fml.javafmlmod.FMLJavaModLanguageProvider; +import net.neoforged.neoforgespi.ILaunchContext; +import net.neoforged.neoforgespi.language.ModFileScanData; +import net.neoforged.neoforgespi.locating.IDiscoveryPipeline; +import net.neoforged.neoforgespi.locating.IModFileCandidateLocator; + +import org.spongepowered.forge.applaunch.loading.moddiscovery.ModFileParsers; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +public final class EnvironmentPluginLocator extends FMLJavaModLanguageProvider implements IModFileCandidateLocator { + + @Override + public void findCandidates(ILaunchContext context, IDiscoveryPipeline pipeline) { + for(Path[] arrayPaths : getPluginsPaths()) for(Path path : arrayPaths) context.addLocated(path); + scanMods().forEach(scan -> { + scan.getIModInfoData().forEach(file -> { + pipeline.addModFile(file.getFile()); + context.addLocated(file.getFile().getFilePath()); + }); + }); + } + + //@Override + public List scanMods() { + final List modFiles = new ArrayList<>(); + for (final Path[] paths : getPluginsPaths()) { + ModFileScanData data = new ModFileScanData(); + data.addModFileInfo(ModFileParsers.newPluginInstance(this, paths).getModFileInfo()); + } + return modFiles; + } + + //@Override + protected ModFileScanData createMod(Path path) { + ModFileScanData data = new ModFileScanData(); + data.addModFileInfo(ModFileParsers.newPluginInstance(this, path).getModFileInfo()); + return data; + } + + @Override + public String name() { + return "environment plugin"; + } + + //@Override + public void initArguments(final Map arguments) { + } + + private static List getPluginsPaths() { + final String env = System.getenv("SPONGE_PLUGINS"); + if (env == null) { + return Collections.emptyList(); + } + + List plugins = new ArrayList<>(); + for (final String entry : env.split(";")) { + if (entry.isBlank()) { + continue; + } + plugins.add(Stream.of(entry.split("&")).map(Path::of).toArray(Path[]::new)); + } + + return plugins; + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/PluginsDirectoryLocator.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/PluginsDirectoryLocator.java new file mode 100755 index 00000000000..8a1211aae7f --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/PluginsDirectoryLocator.java @@ -0,0 +1,94 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.loading.moddiscovery.locator; + +import cpw.mods.util.LambdaExceptionUtils; + +import net.neoforged.fml.javafmlmod.FMLJavaModLanguageProvider; +import net.neoforged.fml.loading.ModDirTransformerDiscoverer; +import net.neoforged.fml.loading.StringUtils; +import net.neoforged.fml.loading.moddiscovery.ModFile; +import net.neoforged.neoforgespi.ILaunchContext; +import net.neoforged.neoforgespi.language.ModFileScanData; +import net.neoforged.neoforgespi.locating.IDiscoveryPipeline; +import net.neoforged.neoforgespi.locating.IModFileCandidateLocator; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import org.spongepowered.common.applaunch.AppLaunch; +import org.spongepowered.forge.applaunch.loading.moddiscovery.ModFileParsers; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +public final class PluginsDirectoryLocator extends FMLJavaModLanguageProvider implements IModFileCandidateLocator { + private static final Logger LOGGER = LogManager.getLogger(); + + final List modFiles = new ArrayList<>(); + + @Override + public void findCandidates(ILaunchContext context, IDiscoveryPipeline pipeline) { + final List pluginDirectories = AppLaunch.pluginPlatform().pluginDirectories(); + + for (final Path paths : pluginDirectories) { + this.scanForModsIn(paths).forEach(this::addData); + } + } + + public List getScanData() { + return modFiles; + } + + private Stream scanForModsIn(final Path pluginsDirectory) { + + final List excluded = ModDirTransformerDiscoverer.allExcluded(); + return LambdaExceptionUtils.uncheck(() -> Files.list(pluginsDirectory)) + .filter((p) -> !excluded.contains(p) && StringUtils.toLowerCase(p.getFileName().toString()).endsWith(".jar")) + .sorted(Comparator.comparing((path) -> StringUtils.toLowerCase(path.getFileName().toString()))) + .map((p) -> ModFileParsers.newPluginInstance(this, p)) + .filter(ModFile::identifyMods); + } + + @Override + public String name() { + return "plugins directory"; + } + + //@Override + public void initArguments(final Map arguments) { + } + + private void addData(ModFile modFile) { + ModFileScanData data = new ModFileScanData(); + data.addModFileInfo(modFile.getModFileInfo()); + modFiles.add(data); + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/plugin/ForgePluginPlatform.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/plugin/ForgePluginPlatform.java new file mode 100755 index 00000000000..6ba748612e1 --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/plugin/ForgePluginPlatform.java @@ -0,0 +1,134 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.plugin; + +import cpw.mods.modlauncher.Environment; +import cpw.mods.modlauncher.api.IEnvironment; + +import net.neoforged.fml.loading.FMLPaths; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.spongepowered.common.applaunch.AppLaunch; +import org.spongepowered.common.applaunch.config.core.SpongeConfigs; +import org.spongepowered.common.applaunch.plugin.PluginPlatform; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class ForgePluginPlatform implements PluginPlatform { + + private static volatile boolean bootstrapped; + + private final Environment environment; + private final Logger logger; + private final List pluginDirectories; + + /** + * Bootstrap + * @param environment + * @return + */ + public static synchronized boolean bootstrap(final Environment environment) { + if (ForgePluginPlatform.bootstrapped) { + return false; + } + ForgePluginPlatform.bootstrapped = true; + final ForgePluginPlatform platform = new ForgePluginPlatform(environment); + AppLaunch.setPluginPlatform(platform); + platform.init(); + return true; + } + + private ForgePluginPlatform(final Environment environment) { + this.environment = environment; + this.logger = LogManager.getLogger("plugin"); + this.pluginDirectories = new ArrayList<>(); + + this.pluginDirectories.add(FMLPaths.MODSDIR.get()); + } + + @Override + public String version() { + return this.environment.getProperty(IEnvironment.Keys.VERSION.get()).orElse("dev"); + } + + @Override + public void setVersion(final String version) { + // NOOP + } + + @Override + public Logger logger() { + return this.logger; + } + + @Override + public Path baseDirectory() { + return this.environment.getProperty(IEnvironment.Keys.GAMEDIR.get()).orElse(Paths.get(".")); + } + + @Override + public void setBaseDirectory(final Path baseDirectory) { + // NOOP + } + + @Override + public List pluginDirectories() { + return Collections.unmodifiableList(this.pluginDirectories); + } + + @Override + public void setPluginDirectories(final List pluginDirectories) { + // NOOP + } + + // TODO: Zidane, how will this work with SF? + @Override + public String metadataFilePath() { + return null; + } + + @Override + public void setMetadataFilePath(final String metadataFilePath) { + // NOOP + } + + public void init() { + final Path alternativePluginsDirectory = Paths.get(SpongeConfigs.getCommon().get().general.pluginsDir.getParsed()); + try { + Files.createDirectories(alternativePluginsDirectory); + } catch (final IOException e) { + throw new RuntimeException(e); + } + + this.pluginDirectories.add(alternativePluginsDirectory); + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/ListenerTransformer.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/ListenerTransformer.java new file mode 100755 index 00000000000..3990525693b --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/ListenerTransformer.java @@ -0,0 +1,100 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.transformation; + +import cpw.mods.modlauncher.api.*; +import net.neoforged.fml.loading.LoadingModList; +import net.neoforged.fml.loading.moddiscovery.ModFileInfo; +import net.neoforged.neoforgespi.language.ModFileScanData; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import java.util.HashSet; +import java.util.Set; + +import static org.objectweb.asm.Opcodes.*; + +public class ListenerTransformer implements ITransformer { + + @NonNull + @Override + public ClassNode transform(final ClassNode input, final ITransformerVotingContext context) { + MethodNode clinit = null; + for (final MethodNode method : input.methods) { + if (method.name.equals("") && method.desc.equals("()V")) { + clinit = method; + break; + } + } + + if (clinit == null) { + clinit = new MethodNode(ACC_STATIC, "", "()V", null, null); + clinit.instructions.add(new InsnNode(RETURN)); + input.methods.add(clinit); + } + + + final InsnList list = new InsnList(); + list.add(new LdcInsnNode(Type.getObjectType(input.name))); + list.add(new MethodInsnNode(INVOKESTATIC, "java/lang/invoke/MethodHandles", "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", false)); + list.add(new MethodInsnNode(INVOKESTATIC, "org/spongepowered/forge/launch/event/ListenerLookups", "set", "(Ljava/lang/Class;Ljava/lang/invoke/MethodHandles$Lookup;)V")); + + clinit.instructions.insert(list); + + return input; + } + + @NonNull + @Override + public TransformerVoteResult castVote(final ITransformerVotingContext context) { + return context.getReason().equals(ITransformerActivity.CLASSLOADING_REASON) ? TransformerVoteResult.YES : TransformerVoteResult.NO; + } + + @Override + public Set> targets() { + final Type listenerType = Type.getType("Lorg/spongepowered/api/event/Listener;"); + + final Set listenerClasses = new HashSet<>(); + for (ModFileInfo fileInfo : LoadingModList.get().getModFiles()) { + for (ModFileScanData.AnnotationData annotation : fileInfo.getFile().getScanResult().getAnnotations()) { + if (listenerType.equals(annotation.annotationType())) { + listenerClasses.add(annotation.clazz()); + } + } + } + + final Set> targets = new HashSet<>(); + for (Type listener : listenerClasses) { + targets.add(Target.targetClass(listener.getInternalName())); + } + return targets; + } + + @Override + public TargetType getTargetType() { + return TargetType.CLASS; + } +} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/SpongeForgeTransformationService.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/SpongeForgeTransformationService.java new file mode 100755 index 00000000000..0849a65b284 --- /dev/null +++ b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/SpongeForgeTransformationService.java @@ -0,0 +1,155 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.applaunch.transformation; + +import cpw.mods.jarhandling.SecureJar; +import cpw.mods.modlauncher.Environment; +import cpw.mods.modlauncher.Launcher; +import cpw.mods.modlauncher.api.*; + +import joptsimple.OptionSpec; +import joptsimple.OptionSpecBuilder; + +import net.neoforged.fml.loading.LoadingModList; +import net.neoforged.fml.loading.moddiscovery.ModFileInfo; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.spongepowered.transformers.modlauncher.AccessWidenerTransformationService; +import org.spongepowered.transformers.modlauncher.SuperclassChanger; + +import java.net.MalformedURLException; +import java.nio.file.Path; +import java.util.List; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Supplier; +import java.util.jar.Attributes; + +public class SpongeForgeTransformationService implements ITransformationService { + private static final Logger LOGGER = LogManager.getLogger(); + + private OptionSpec checkHashes; + private OptionSpec librariesDirectoryName; + + @NonNull + @Override + public String name() { + return "spongeforge"; + } + + @Override + public void arguments(final BiFunction argumentBuilder) { + this.checkHashes = argumentBuilder.apply("checkHashes", "Whether to check hashes when downloading libraries") + .withOptionalArg() + .ofType(Boolean.class) + .defaultsTo(true); + this.librariesDirectoryName = argumentBuilder.apply("librariesDir", "The directory to download SpongeForge libraries to") + .withOptionalArg() + .ofType(String.class) + .defaultsTo("sponge-libraries"); + } + + @Override + public void argumentValues(final OptionResult option) { + Launcher.INSTANCE.environment().computePropertyIfAbsent(Keys.CHECK_LIBRARY_HASHES.get(), $ -> option.value(this.checkHashes)); + Launcher.INSTANCE.environment().computePropertyIfAbsent(Keys.LIBRARIES_DIRECTORY.get(), + $ -> Launcher.INSTANCE.environment().getProperty(IEnvironment.Keys.GAMEDIR.get()) + .orElseThrow(() -> new IllegalStateException("No game directory was available")) + .resolve(option.value(this.librariesDirectoryName))); + } + + @Override + public void initialize(final IEnvironment environment) { + } + + @Override + public void onLoad(final IEnvironment env, final Set otherServices) { + } + + @Override + public List completeScan(IModuleLayerManager layerManager) { + final Environment env = Launcher.INSTANCE.environment(); + final AccessWidenerTransformationService accessWidener = env.getProperty(AccessWidenerTransformationService.INSTANCE.get()).orElse(null); + final SuperclassChanger superclassChanger = env.getProperty(SuperclassChanger.INSTANCE.get()).orElse(null); + + if (accessWidener != null || superclassChanger != null) { + // TODO move this inside modlauncher-transformers when updating SpongeVanilla to latest ModLauncher + for (ModFileInfo fileInfo : LoadingModList.get().getModFiles()) { + final SecureJar jar = fileInfo.getFile().getSecureJar(); + final Attributes attributes = jar.moduleDataProvider().getManifest().getMainAttributes(); + + if (accessWidener != null) { + final String awPaths = attributes.getValue("Access-Widener"); + if (awPaths != null) { + final String jarFileName = fileInfo.getFile().getFileName(); + LOGGER.debug("Registering access wideners from {} ...", jarFileName); + + for (final String awPath : awPaths.split(",")) { + try { + accessWidener.offerResource(jar.getPath(awPath).toUri().toURL(), awPath); + } catch (final MalformedURLException e) { + LOGGER.warn("Failed to register access widener {} from {}", awPath, jarFileName, e); + } + } + } + } + + if (superclassChanger != null) { + final String scPaths = attributes.getValue("Superclass-Transformer"); + if (scPaths != null) { + final String jarFileName = fileInfo.getFile().getFileName(); + LOGGER.debug("Registering superclass changers from {} ...", jarFileName); + + for (final String scPath : scPaths.split(",")) { + try { + superclassChanger.offerResource(jar.getPath(scPath).toUri().toURL(), scPath); + } catch (final MalformedURLException e) { + LOGGER.warn("Failed to register superclass changer {} from {}", scPath, jarFileName, e); + } + } + } + } + } + } + + return List.of(); + } + + @Override + public List> transformers() { + return List.of(new ListenerTransformer()); + } + + public static final class Keys { + + public static final Supplier> CHECK_LIBRARY_HASHES = IEnvironment.buildKey("sponge:check_library_hashes", Boolean.class); + public static final Supplier> LIBRARIES_DIRECTORY = IEnvironment.buildKey("sponge:libraries_directory", Path.class); + + private Keys() { + } + + } +} diff --git a/neoforge/src/applaunch/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService b/neoforge/src/applaunch/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService new file mode 100755 index 00000000000..ced7680d190 --- /dev/null +++ b/neoforge/src/applaunch/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService @@ -0,0 +1 @@ +org.spongepowered.forge.applaunch.transformation.SpongeForgeTransformationService diff --git a/neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IDependencyLocator b/neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IDependencyLocator new file mode 100755 index 00000000000..97ede6493ca --- /dev/null +++ b/neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IDependencyLocator @@ -0,0 +1 @@ +org.spongepowered.forge.applaunch.loading.moddiscovery.SpongeForgeDependencyLocator \ No newline at end of file diff --git a/neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator b/neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator new file mode 100755 index 00000000000..ad02e10d0d0 --- /dev/null +++ b/neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator @@ -0,0 +1,3 @@ +org.spongepowered.forge.applaunch.loading.moddiscovery.SpongeForgeModLocator +org.spongepowered.forge.applaunch.loading.moddiscovery.locator.EnvironmentPluginLocator +org.spongepowered.forge.applaunch.loading.moddiscovery.locator.PluginsDirectoryLocator \ No newline at end of file diff --git a/neoforge/src/lang/java/org/spongepowered/forge/lang/provider/JavaPluginLanguageProvider.java b/neoforge/src/lang/java/org/spongepowered/forge/lang/provider/JavaPluginLanguageProvider.java new file mode 100755 index 00000000000..c0ecc3175d5 --- /dev/null +++ b/neoforge/src/lang/java/org/spongepowered/forge/lang/provider/JavaPluginLanguageProvider.java @@ -0,0 +1,134 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.lang.provider; + +import cpw.mods.util.LambdaExceptionUtils; +import net.neoforged.fml.Logging; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.ModLoadingContext; +import net.neoforged.fml.ModLoadingException; +import net.neoforged.fml.javafmlmod.FMLJavaModLanguageProvider; +import net.neoforged.neoforgespi.language.IModInfo; +import net.neoforged.neoforgespi.language.IModLanguageLoader; +import net.neoforged.neoforgespi.language.ModFileScanData; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.objectweb.asm.Type; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.Collectors; + +public final class JavaPluginLanguageProvider extends FMLJavaModLanguageProvider { + + private static final Type PLUGIN_ANNOTATION = Type.getType("Lorg/spongepowered/plugin/builtin/jvm/Plugin;"); + + private final Logger logger; + + public JavaPluginLanguageProvider() { + this.logger = LogManager.getLogger(); + } + + @Override + public String name() { + return "java_plain"; + } +/* + @Override + public Consumer getFileVisitor() { + return scanResult -> { + final Map modTargetMap = scanResult.getAnnotations().stream() + .filter(ad -> ad.annotationType().equals(JavaPluginLanguageProvider.PLUGIN_ANNOTATION)) + .peek(ad -> this.logger.debug(Logging.SCAN, "Found @Plugin class {} with id {}", ad.clazz().getClassName(), ad.annotationData().get("value"))) + .map(ad -> new PluginTarget(ad.clazz().getClassName(), (String)ad.annotationData().get("value"))) + .collect(Collectors.toMap(PluginTarget::getPlugin, Function.identity(), (a,b)->a)); + scanResult.addLanguageLoader(modTargetMap); + }; + }*/ + + private static final class PluginTarget implements IModLanguageLoader { + + private final Logger logger; + private final String className; + private final String plugin; + + private PluginTarget(final String className, final String plugin) { + this.logger = LogManager.getLogger(); + this.className = className; + this.plugin = plugin; + } + + @Override + public ModContainer loadMod(final IModInfo info, final ModFileScanData modFileScanData, final ModuleLayer gameLayer) { + // The following is adapted from FMLJavaModLanguageProvider.FMLModTarget + + // This language class is loaded in the system level classloader - before the game even starts + // So we must treat container construction as an arms length operation, and load the container + // in the classloader of the game - the context classloader is appropriate here. + try { + final Class pluginContainer = Class.forName( + "org.spongepowered.forge.launch.plugin.PluginModContainer", true, Thread.currentThread().getContextClassLoader()); + this.logger.debug(Logging.LOADING, "Loading PluginModContainer from classloader {} - got {}", Thread.currentThread().getContextClassLoader(), pluginContainer.getClassLoader()); + final Constructor constructor = pluginContainer.getConstructor(IModInfo.class, String.class, ModFileScanData.class, ModuleLayer.class); + return (ModContainer) constructor.newInstance(info, className, modFileScanData, gameLayer); + } + // ALL exception handling has to be done through the classloader, because we're loaded in the wrong context, so any classes we just blind load will be in the wrong + // class loading context. Funky but works. + catch (final InvocationTargetException e) { + this.logger.fatal(Logging.LOADING, "Failed to build plugin", e); + final Class mle = (Class) LambdaExceptionUtils.uncheck(()->Class.forName("net.neoforged.fml.ModLoadingException", true, Thread.currentThread().getContextClassLoader())); + if (mle.isInstance(e.getTargetException())) { + throw mle.cast(e.getTargetException()); + } else { + final Class mls = (Class) LambdaExceptionUtils.uncheck(()->Class.forName("net.neoforged.fml.ModLoadingContext", true, Thread.currentThread().getContextClassLoader())); + throw LambdaExceptionUtils.uncheck(()->LambdaExceptionUtils.uncheck(()->mle.getConstructor(IModInfo.class, mls, String.class, Throwable.class)).newInstance(info, mls, "fml.modloading.failedtoloadmodclass", e)); + } + } + catch (final NoSuchMethodException | ClassNotFoundException | InstantiationException | IllegalAccessException e) { + this.logger.fatal(Logging.LOADING,"Unable to load PluginModContainer, excuse me?", e); + final Class mle = (Class)LambdaExceptionUtils.uncheck(()->Class.forName("net.neoforged.fml.ModLoadingException", true, Thread.currentThread().getContextClassLoader())); + final Class mls = (Class) LambdaExceptionUtils.uncheck(()->Class.forName("net.neoforged.fml.ModLoadingContext", true, Thread.currentThread().getContextClassLoader())); + throw LambdaExceptionUtils.uncheck(()->LambdaExceptionUtils.uncheck(()->mle.getConstructor(IModInfo.class, mls, String.class, Throwable.class)).newInstance(info, mls, "fml.modloading.failedtoloadmodclass", e)); + } + } + + public String getPlugin() { + return this.plugin; + } + + @Override + public String name() { + return ""; + } + + @Override + public String version() { + return ""; + } + } +} diff --git a/neoforge/src/lang/resources/META-INF/services/net.minecraftforge.forgespi.language.IModLanguageProvider b/neoforge/src/lang/resources/META-INF/services/net.minecraftforge.forgespi.language.IModLanguageProvider new file mode 100755 index 00000000000..1f6b5fa2dfd --- /dev/null +++ b/neoforge/src/lang/resources/META-INF/services/net.minecraftforge.forgespi.language.IModLanguageProvider @@ -0,0 +1 @@ +org.spongepowered.forge.lang.provider.JavaPluginLanguageProvider \ No newline at end of file diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeLaunch.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeLaunch.java new file mode 100755 index 00000000000..3c96f27755d --- /dev/null +++ b/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeLaunch.java @@ -0,0 +1,106 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.launch; + +import com.google.common.collect.Lists; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Module; +import com.google.inject.Stage; + +import net.neoforged.api.distmarker.Dist; +import net.neoforged.fml.loading.FMLLoader; +import net.neoforged.fml.loading.moddiscovery.ModInfo; +import org.spongepowered.common.applaunch.plugin.PluginPlatform; +import org.spongepowered.common.inject.SpongeCommonModule; +import org.spongepowered.common.inject.SpongeModule; +import org.spongepowered.common.launch.Launch; +import org.spongepowered.common.launch.mapping.SpongeMappingManager; +import org.spongepowered.forge.applaunch.loading.metadata.PluginMetadataUtils; +import org.spongepowered.forge.launch.inject.SpongeForgeModule; +import org.spongepowered.forge.launch.plugin.ForgePluginManager; +import org.spongepowered.plugin.PluginContainer; +import org.spongepowered.plugin.metadata.PluginMetadata; + +import java.util.List; + +public final class ForgeLaunch extends Launch { + + private final ForgePluginManager pluginManager; + private PluginContainer spongeForgePlugin; + private final ForgeMappingManager mappings = new ForgeMappingManager(); + + public ForgeLaunch(final PluginPlatform platform) { + super(platform); + this.pluginManager = new ForgePluginManager(); + } + + @Override + public boolean dedicatedServer() { + return FMLLoader.getDist() == Dist.DEDICATED_SERVER; + } + + @Override + public ForgePluginManager pluginManager() { + return this.pluginManager; + } + + @Override + public SpongeMappingManager mappingManager() { + return this.mappings; + } + + @Override + public Stage injectionStage() { + return FMLLoader.isProduction() ? Stage.PRODUCTION : Stage.DEVELOPMENT; + } + + @Override + public Injector createInjector() { + final List modules = Lists.newArrayList( + new SpongeModule(), + new SpongeCommonModule(), + new SpongeForgeModule() + ); + return Guice.createInjector(this.injectionStage(), modules); + } + + @Override + public PluginContainer platformPlugin() { + if (this.spongeForgePlugin == null) { + this.spongeForgePlugin = this.pluginManager().plugin("spongeforge").orElse(null); + + if (this.spongeForgePlugin == null) { + throw new RuntimeException("Could not find the plugin representing SpongeForge, this is a serious issue!"); + } + } + + return this.spongeForgePlugin; + } + + public PluginMetadata metadataForMod(final ModInfo info) { + return PluginMetadataUtils.modToPlugin(info); + } +} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeMappingManager.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeMappingManager.java new file mode 100755 index 00000000000..5f994c49899 --- /dev/null +++ b/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeMappingManager.java @@ -0,0 +1,61 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.launch; + +import com.google.common.collect.ImmutableMap; +import net.neoforged.fml.loading.FMLEnvironment; +import org.spongepowered.common.launch.mapping.SpongeMappingManager; + +import java.util.Map; + +final class ForgeMappingManager implements SpongeMappingManager { + + // todo: something better + + private static final Map METHOD_MAPPINGS = ImmutableMap.of( + "neighborChanged", "func_220069_a", + "entityInside", "func_196262_a", + "stepOn", "func_176199_a", + "playerTouch", "func_70100_b_" + ); + + private static final Map FIELD_MAPPINGS = ImmutableMap.of( + ); + + @Override + public String toRuntimeClassName(final String srcName) { + return srcName; + } + + @Override + public String toRuntimeFieldName(final Class owner, final String srcName) { + return FMLEnvironment.production ? ForgeMappingManager.FIELD_MAPPINGS.getOrDefault(srcName, srcName) : srcName; + } + + @Override + public String toRuntimeMethodName(final Class owner, final String srcName, final Class... params) { + return FMLEnvironment.production ? ForgeMappingManager.METHOD_MAPPINGS.getOrDefault(srcName, srcName) : srcName; + } +} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgePlatform.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgePlatform.java new file mode 100755 index 00000000000..0f538863862 --- /dev/null +++ b/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgePlatform.java @@ -0,0 +1,50 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.launch; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import org.spongepowered.api.MinecraftVersion; +import org.spongepowered.common.SpongePlatform; + +import java.util.Map; + +@Singleton +public final class ForgePlatform extends SpongePlatform { + + @Inject + public ForgePlatform(final MinecraftVersion minecraftVersion) { + super(minecraftVersion); + } + + @Override + public Map asMap() { + if (this.platformMap.isEmpty()) { + this.createPlatformMetadata(); + } + + return this.platformMap; + } +} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/ForgeEventBridge_Forge.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/ForgeEventBridge_Forge.java new file mode 100755 index 00000000000..446b84fe464 --- /dev/null +++ b/neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/ForgeEventBridge_Forge.java @@ -0,0 +1,61 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.launch.bridge.event; + +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.api.event.Event; + +public interface ForgeEventBridge_Forge { + + /** + * Syncs the Sponge event to this Forge event + * + *

Note that a Sponge event might service multiple Forge events, so any + * syncing should be limited to the remit of this event only (i.e., if the + * event fires for multiple positions, the sync should only consider the + * positions this event is concerned with)

+ * + * @param event The Sponge event + */ + void bridge$syncFrom(Event event); + + /** + * Syncs the Forge event to this Sponge event + * + *

Note that a Sponge event might service multiple Forge events, so any + * syncing should be limited to the remit of this event only (that is, this + * should only affect the Sponge event as far as the remit of this event goes, + * most likely not cancelling events but invalidating transactions.)

+ * + * @param event The Sponge event + */ + void bridge$syncTo(Event event); + + /** + * Creates a Sponge event from this Forge event + */ + @Nullable Event bridge$createSpongeEvent(); + +} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/SpongeEventBridge_Forge.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/SpongeEventBridge_Forge.java new file mode 100755 index 00000000000..c8e4b64be36 --- /dev/null +++ b/neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/SpongeEventBridge_Forge.java @@ -0,0 +1,59 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.launch.bridge.event; + +import net.neoforged.bus.api.Event; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.Collection; + +public interface SpongeEventBridge_Forge { + + /** + * Creates a Forge {@link Event} that must also implement + * {@link ForgeEventBridge_Forge} - not doing so will cause + * an error. + * + *

By default, this returns null.

+ * + * @return The Forge event + */ + default @Nullable Collection bridge$createForgeEvents() { + return null; + } + + /** + * If there is a specialist dispatcher that we need to use for + * this given event, it can be defined here. + * + * @return The dispatcher to use. + * + * IEventBusInvokeDispatcher REMOVED IN NEOFORGE! + */ + /*default IEventBusInvokeDispatcher bridge$eventDispatcher() { + return EventListener::invoke; + }*/ + +} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/command/ForgeCommandManager.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/command/ForgeCommandManager.java new file mode 100755 index 00000000000..035b9af6f1e --- /dev/null +++ b/neoforge/src/launch/java/org/spongepowered/forge/launch/command/ForgeCommandManager.java @@ -0,0 +1,108 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.launch.command; + +import com.google.common.base.Throwables; +import com.google.inject.Inject; +import com.google.inject.Provider; +import com.mojang.brigadier.ParseResults; +import com.mojang.brigadier.context.CommandContextBuilder; +import com.mojang.brigadier.context.ParsedArgument; +import com.mojang.brigadier.exceptions.CommandSyntaxException; + +import net.kyori.adventure.text.Component; + +import net.minecraft.commands.CommandSourceStack; + +import net.neoforged.bus.api.EventPriority; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.CommandEvent; +import org.spongepowered.api.Game; +import org.spongepowered.api.command.CommandCause; +import org.spongepowered.api.command.CommandResult; +import org.spongepowered.api.command.exception.CommandException; +import org.spongepowered.api.command.manager.CommandMapping; +import org.spongepowered.api.command.registrar.CommandRegistrar; +import org.spongepowered.common.command.brigadier.SpongeStringReader; +import org.spongepowered.common.command.manager.SpongeCommandManager; +import org.spongepowered.common.command.registrar.BrigadierBasedRegistrar; +import org.spongepowered.common.command.sponge.SpongeCommand; + +import java.util.Collections; + +public final class ForgeCommandManager extends SpongeCommandManager { + + @Inject + public ForgeCommandManager(final Game game, final Provider spongeCommand) { + super(game, spongeCommand); + } + + @Override + public CommandResult processCommand(final CommandCause cause, final CommandMapping mapping, + final String command, final String args) + throws CommandException { + final String original = args.isEmpty() ? command : (command + " " + args); // TODO SF 1.19.4, should we pass the original string as a param? + + final CommandRegistrar registrar = mapping.registrar(); + final boolean isBrig = registrar instanceof BrigadierBasedRegistrar; + final ParseResults parseResults; + if (isBrig) { + parseResults = this.getDispatcher().parse(original, (CommandSourceStack) cause); + } else { + // We have a non Brig registrar, so we just create a dummy result for mods to inspect. + final CommandContextBuilder contextBuilder = new CommandContextBuilder<>( + this.getDispatcher(), + (CommandSourceStack) cause, + this.getDispatcher().getRoot(), + 0); + contextBuilder.withCommand(ctx -> 1); + if (!args.isEmpty()) { + contextBuilder.withArgument("parsed", new ParsedArgument<>(command.length(), original.length(), args)); + } + parseResults = new ParseResults<>(contextBuilder, new SpongeStringReader(original), Collections.emptyMap()); + } + + // Relocated from Commands (injection short circuits it there) + final CommandEvent event = new CommandEvent(parseResults); + if (!NeoForge.EVENT_BUS.post(EventPriority.NORMAL, event).isCanceled()) { + if (event.getException() != null) { + Throwables.throwIfUnchecked(event.getException()); + } + // As per Forge, we just treat it as a zero success, and do nothing with it. + return CommandResult.builder().result(0).build(); + } + + if (isBrig) { + try { + return CommandResult.builder().result(this.getDispatcher().execute(parseResults)).build(); + } catch (CommandSyntaxException e) { + throw new CommandException(Component.empty(), e); // TODO SF 1.19.4, what message should we put there? + } + } else { + return mapping.registrar().process(cause, mapping, command, args); + } + } + +} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/event/ForgeEventManager.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/event/ForgeEventManager.java new file mode 100755 index 00000000000..4f604e67cc0 --- /dev/null +++ b/neoforge/src/launch/java/org/spongepowered/forge/launch/event/ForgeEventManager.java @@ -0,0 +1,168 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.launch.event; + +import com.google.inject.Singleton; + +import net.neoforged.bus.api.Event; +import net.neoforged.bus.api.EventListener; +import net.neoforged.bus.api.EventPriority; +import net.neoforged.bus.api.IEventBus; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import org.spongepowered.common.event.manager.RegisteredListener; +import org.spongepowered.common.event.manager.SpongeEventManager; +import org.spongepowered.forge.launch.bridge.event.ForgeEventBridge_Forge; +import org.spongepowered.forge.launch.bridge.event.SpongeEventBridge_Forge; +import org.spongepowered.plugin.PluginContainer; + +import java.lang.invoke.MethodHandles; +import java.util.Collection; +import java.util.List; +import java.util.function.Consumer; + +@Singleton +public final class ForgeEventManager extends SpongeEventManager implements IEventBus { + + private final IEventBus wrappedEventBus; + + public ForgeEventManager(final IEventBus eventBus) { + this.wrappedEventBus = eventBus; + } + + // IEventBus + + @Override + public void register(final Object target) { + this.wrappedEventBus.register(target); + } + + @Override + public void addListener(final Consumer consumer) { + this.wrappedEventBus.addListener(consumer); + } + + @Override + public void addListener(Class eventType, Consumer consumer) { + + } + + @Override + public void addListener(final EventPriority priority, final Consumer consumer) { + this.wrappedEventBus.addListener(priority, consumer); + } + + @Override + public void addListener(EventPriority priority, Class eventType, Consumer consumer) { + this.wrappedEventBus.addListener(priority, eventType, consumer); + } + + @Override + public void addListener(final EventPriority priority, final boolean receiveCancelled, final Consumer consumer) { + this.wrappedEventBus.addListener(priority, receiveCancelled, consumer); + } + + @Override + public void addListener(final EventPriority priority, final boolean receiveCancelled, final Class eventType, final Consumer consumer) { + this.wrappedEventBus.addListener(priority, receiveCancelled, eventType, consumer); + } + + @Override + public void addListener(boolean receiveCanceled, Consumer consumer) { + this.wrappedEventBus.addListener(receiveCanceled, consumer); + } + + @Override + public void addListener(boolean receiveCanceled, Class eventType, Consumer consumer) { + this.wrappedEventBus.addListener(receiveCanceled, eventType, consumer); + } + + @Override + public void unregister(final Object object) { + this.wrappedEventBus.unregister(object); + } + + @Override + public T post(T event) { + return wrappedEventBus.post(event); + } + + @Override + public T post(EventPriority phase, T event) { + return wrappedEventBus.post(phase, event); + } + + @Override + public void start() { + this.wrappedEventBus.start(); + } + + // EventManager + + @Override + protected MethodHandles.@Nullable Lookup getLookup(final PluginContainer plugin, final Class handle) { + return ListenerLookups.get(handle); + } + + @Override + public boolean post(final org.spongepowered.api.event.Event event) { + final SpongeEventBridge_Forge eventBridge = ((SpongeEventBridge_Forge) event); + final @Nullable Collection forgeEvents = eventBridge.bridge$createForgeEvents(); + if (forgeEvents == null || forgeEvents.isEmpty()) { + // Do as SpongeVanilla does - Forge has no role to play here. + return super.post(event); + } + return this.postDualBus(event, forgeEvents); + } + + // Implementation + + private boolean postDualBus(final org.spongepowered.api.event.Event spongeEvent, final Collection forgeEvents) { + try (final NoExceptionClosable ignored = this.preparePost(spongeEvent)) { + final RegisteredListener.Cache listeners = this.getHandlerCache(spongeEvent); + final List> beforeModifications = listeners.beforeModifications(); + if (!beforeModifications.isEmpty()) { + // First, we fire the Sponge beforeModifications on the Sponge event + this.post(spongeEvent, beforeModifications); + + // Then we sync to the Forge events + for (final Event forgeEvent : forgeEvents) { + ((ForgeEventBridge_Forge) forgeEvent).bridge$syncFrom(spongeEvent); + } + } + // Then, we fire all our Forge events + for (final Event forgeEvent : forgeEvents) { + this.wrappedEventBus.post(forgeEvent); + // We must sync back the event's changes, if there are any. + // For complex events, this will be a partial sync. + ((ForgeEventBridge_Forge) forgeEvent).bridge$syncTo(spongeEvent); + } + + // and now we do our standard event listener stuff. + return this.post(spongeEvent, listeners.afterModifications()); + } + } +} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/event/ListenerLookups.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/event/ListenerLookups.java new file mode 100755 index 00000000000..0ab48d288c8 --- /dev/null +++ b/neoforge/src/launch/java/org/spongepowered/forge/launch/event/ListenerLookups.java @@ -0,0 +1,43 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.launch.event; + +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.lang.invoke.MethodHandles; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class ListenerLookups { + private static final Map, MethodHandles.Lookup> lookups = new ConcurrentHashMap<>(); + + public static MethodHandles.@Nullable Lookup get(final Class listenerClass) { + return ListenerLookups.lookups.get(listenerClass); + } + + public static void set(final Class listenerClass, final MethodHandles.Lookup lookup) { + ListenerLookups.lookups.put(listenerClass, lookup); + } +} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/event/SpongeEventBus.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/event/SpongeEventBus.java new file mode 100755 index 00000000000..69ff612bd03 --- /dev/null +++ b/neoforge/src/launch/java/org/spongepowered/forge/launch/event/SpongeEventBus.java @@ -0,0 +1,103 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.launch.event; + +import net.neoforged.bus.*; +import net.neoforged.bus.api.*; + +import java.lang.reflect.Field; +import java.util.Objects; + +public final class SpongeEventBus extends EventBus { + + // I hope ya'll like reflection... + private static Field busIDField; + private static Field exceptionHandlerField; + private static Field trackPhasesField; + private static Field shutdownField; + private static Field baseTypeField; + private static Field checkTypesOnDispatchField; + + static { + try { + SpongeEventBus.busIDField = EventBus.class.getDeclaredField("busID"); + SpongeEventBus.exceptionHandlerField = EventBus.class.getDeclaredField("exceptionHandler"); + SpongeEventBus.trackPhasesField = EventBus.class.getDeclaredField("trackPhases"); + SpongeEventBus.shutdownField = EventBus.class.getDeclaredField("shutdown"); + SpongeEventBus.baseTypeField = EventBus.class.getDeclaredField("baseType"); + SpongeEventBus.checkTypesOnDispatchField = EventBus.class.getDeclaredField("checkTypesOnDispatch"); + + } catch (final Exception ex) { + // Burn this to the ground + throw new RuntimeException(ex); + } + } + + // reflected fields that are stored again to prevent multiple reflection calls + private final int rbusID; + private final IEventExceptionHandler rexceptionHandler; + private final boolean rtrackPhases; + private boolean rshutdown; + private final Class rbaseType; + private final boolean rcheckTypesOnDispatch; + + public SpongeEventBus(final BusBuilderImpl busBuilder) { + super(busBuilder); + + // Sponge Start - I hope ya'll still like reflection + try { + SpongeEventBus.busIDField.setAccessible(true); + SpongeEventBus.exceptionHandlerField.setAccessible(true); + SpongeEventBus.trackPhasesField.setAccessible(true); + SpongeEventBus.shutdownField.setAccessible(true); + SpongeEventBus.baseTypeField.setAccessible(true); + SpongeEventBus.checkTypesOnDispatchField.setAccessible(true); + + this.rbusID = SpongeEventBus.busIDField.getInt(this); + this.rexceptionHandler = (IEventExceptionHandler) SpongeEventBus.exceptionHandlerField.get(this); + this.rtrackPhases = SpongeEventBus.trackPhasesField.getBoolean(this); + this.rshutdown = SpongeEventBus.shutdownField.getBoolean(this); + this.rbaseType = (Class) SpongeEventBus.baseTypeField.get(this); + this.rcheckTypesOnDispatch = SpongeEventBus.checkTypesOnDispatchField.getBoolean(this); + + SpongeEventBus.busIDField.setAccessible(false); + SpongeEventBus.exceptionHandlerField.setAccessible(false); + SpongeEventBus.trackPhasesField.setAccessible(false); + SpongeEventBus.shutdownField.setAccessible(false); + SpongeEventBus.baseTypeField.setAccessible(false); + SpongeEventBus.checkTypesOnDispatchField.setAccessible(false); + } catch (final Exception ex) { + // Burn this to the ground again + throw new RuntimeException(ex); + } + // Sponge End + } + + @Override + public void start() { + super.start(); + this.rshutdown = false; + } +} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/inject/SpongeForgeModule.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/inject/SpongeForgeModule.java new file mode 100755 index 00000000000..fa24af48809 --- /dev/null +++ b/neoforge/src/launch/java/org/spongepowered/forge/launch/inject/SpongeForgeModule.java @@ -0,0 +1,47 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.launch.inject; + +import com.google.inject.AbstractModule; + +import net.neoforged.neoforge.common.NeoForge; + +import org.spongepowered.api.Platform; +import org.spongepowered.api.event.EventManager; +import org.spongepowered.common.command.manager.SpongeCommandManager; +import org.spongepowered.forge.launch.ForgePlatform; +import org.spongepowered.forge.launch.command.ForgeCommandManager; +import org.spongepowered.forge.launch.event.ForgeEventManager; + +public final class SpongeForgeModule extends AbstractModule { + + @Override + protected void configure() { + this.bind(Platform.class).to(ForgePlatform.class); + this.bind(EventManager.class).toProvider(() -> (ForgeEventManager) NeoForge.EVENT_BUS); + this.bind(SpongeCommandManager.class).to(ForgeCommandManager.class); + } + +} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginContainer.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginContainer.java new file mode 100755 index 00000000000..ebdbd9999a0 --- /dev/null +++ b/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginContainer.java @@ -0,0 +1,101 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.launch.plugin; + +import com.google.common.collect.MapMaker; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.loading.moddiscovery.ModInfo; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.spongepowered.common.launch.Launch; +import org.spongepowered.forge.launch.ForgeLaunch; +import org.spongepowered.plugin.PluginContainer; +import org.spongepowered.plugin.metadata.PluginMetadata; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +public class ForgePluginContainer implements PluginContainer { + private final ModContainer modContainer; + + private Logger logger; + private PluginMetadata pluginMetadata; + private Object instance; // Find a way to get the instance of a plugin/mod from NeoForge + + ForgePluginContainer(final ModContainer modContainer) { + this.modContainer = modContainer; + } + + public ModContainer getModContainer() { + return this.modContainer; + } + + @Override + public PluginMetadata metadata() { + if (this.pluginMetadata == null) { + this.pluginMetadata = ((ForgeLaunch) Launch.instance()).metadataForMod((ModInfo) this.modContainer.getModInfo()); + } + return this.pluginMetadata; + } + + @Override + public Logger logger() { + if (this.logger == null) { + this.logger = LogManager.getLogger(this.modContainer.getModId()); + } + return this.logger; + } + + @Override + public Optional locateResource(URI relative) { + Objects.requireNonNull(relative, "relative"); + + final ClassLoader classLoader = this.modContainer.getClass().getClassLoader(); + final URL resolved = classLoader.getResource(relative.getPath()); + try { + if (resolved == null) { + return Optional.empty(); + } + return Optional.of(resolved.toURI()); + } catch (final URISyntaxException ignored) { + return Optional.empty(); + } + } + + @Override + public Object instance() { + return instance; + } + + private static final Map containers = new MapMaker().weakKeys().makeMap(); + + public static ForgePluginContainer of(final ModContainer modContainer) { + return containers.computeIfAbsent(modContainer, ForgePluginContainer::new); + } +} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginManager.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginManager.java new file mode 100755 index 00000000000..0c571c66c94 --- /dev/null +++ b/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginManager.java @@ -0,0 +1,62 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.launch.plugin; + +import com.google.common.collect.ImmutableList; +import com.google.inject.Singleton; +import net.neoforged.fml.ModList; +import net.neoforged.fml.common.Mod; +import org.spongepowered.common.launch.plugin.SpongePluginManager; +import org.spongepowered.plugin.PluginContainer; +import org.spongepowered.plugin.builtin.jvm.Plugin; + +import java.util.Collection; +import java.util.Objects; +import java.util.Optional; + +@Singleton +@SuppressWarnings("unchecked") +public final class ForgePluginManager implements SpongePluginManager { + + @Override + public Optional fromInstance(final Object instance) { + Objects.requireNonNull(instance, "instance"); + if(instance.getClass().isAnnotationPresent(Plugin.class)) return plugin(instance.getClass().getAnnotation(Plugin.class).value()); + if(instance.getClass().isAnnotationPresent(Mod.class)) return plugin(instance.getClass().getAnnotation(Mod.class).value()); + return Optional.empty(); + } + + @Override + public Optional plugin(final String id) { + return ModList.get().getModContainerById(Objects.requireNonNull(id, "id")).map(ForgePluginContainer::of); + } + + @Override + public Collection plugins() { + final ImmutableList.Builder builder = ImmutableList.builder(); + ModList.get().forEachModInOrder(mod -> builder.add(ForgePluginContainer.of(mod))); + return builder.build(); + } +} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/PluginModContainer.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/PluginModContainer.java new file mode 100755 index 00000000000..73f92ca0389 --- /dev/null +++ b/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/PluginModContainer.java @@ -0,0 +1,129 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.launch.plugin; + +import com.google.inject.Injector; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.EventBusErrorMessage; +import net.minecraftforge.eventbus.api.BusBuilder; +import net.minecraftforge.eventbus.api.Event; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.eventbus.api.IEventListener; +import net.minecraftforge.fml.Logging; +import net.minecraftforge.fml.ModContainer; +import net.minecraftforge.fml.ModLoadingException; +import net.minecraftforge.fml.ModLoadingStage; +import net.minecraftforge.fml.event.IModBusEvent; +import net.minecraftforge.fml.javafmlmod.AutomaticEventSubscriber; +import net.minecraftforge.forgespi.language.IModInfo; +import net.minecraftforge.forgespi.language.ModFileScanData; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.spongepowered.common.inject.plugin.PluginModule; +import org.spongepowered.common.launch.Launch; +import org.spongepowered.forge.launch.event.ForgeEventManager; +import org.spongepowered.plugin.PluginContainer; + +import java.util.Optional; + +// Spongified FMLModContainer +public final class PluginModContainer extends ModContainer { + private static final Logger LOGGER = LogManager.getLogger(); + + private final ModFileScanData scanResults; + private final IEventBus eventBus; + private Object modInstance; + private final Class modClass; + + public PluginModContainer(IModInfo info, String className, ModFileScanData modFileScanResults, ModuleLayer gameLayer) { + super(info); + LOGGER.debug(Logging.LOADING, "Creating PluginModContainer instance for {}", className); + this.scanResults = modFileScanResults; + this.activityMap.put(ModLoadingStage.CONSTRUCT, this::constructPlugin); + this.eventBus = BusBuilder.builder().setExceptionHandler(this::onEventFailed).setTrackPhases(false).markerType(IModBusEvent.class).useModLauncher().build(); + this.configHandler = Optional.of(ce -> this.eventBus.post(ce.self())); + this.contextExtension = () -> null; + + try { + Module module = gameLayer.findModule(info.getOwningFile().moduleName()).orElseThrow(); + modClass = Class.forName(module, className); + LOGGER.trace(Logging.LOADING, "Loaded modclass {} with {}", modClass.getName(), modClass.getClassLoader()); + } catch (Throwable e) { + LOGGER.error(Logging.LOADING, "Failed to load class {}", className, e); + throw new ModLoadingException(info, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadmodclass", e); + } + } + + private void onEventFailed(IEventBus iEventBus, Event event, IEventListener[] iEventListeners, int i, Throwable throwable) { + LOGGER.error(new EventBusErrorMessage(event, i, iEventListeners, throwable)); + } + + private void constructPlugin() { + try { + LOGGER.trace(Logging.LOADING, "Loading plugin instance {} of type {}", getModId(), this.modClass.getName()); + + final PluginContainer pluginContainer = ForgePluginContainer.of(this); + final Injector childInjector = Launch.instance().lifecycle().platformInjector().createChildInjector(new PluginModule(pluginContainer, this.modClass)); + this.modInstance = childInjector.getInstance(this.modClass); + ((ForgeEventManager) MinecraftForge.EVENT_BUS).registerListeners(pluginContainer, this.modInstance); + + LOGGER.trace(Logging.LOADING, "Loaded plugin instance {} of type {}", getModId(), this.modClass.getName()); + } catch (Throwable e) { + LOGGER.error(Logging.LOADING, "Failed to create plugin instance. PluginID: {}, class {}", getModId(), this.modClass.getName(), e); + throw new ModLoadingException(this.modInfo, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadmod", e, this.modClass); + } + + try { + LOGGER.trace(Logging.LOADING, "Injecting Automatic event subscribers for {}", getModId()); + AutomaticEventSubscriber.inject(this, this.scanResults, this.modClass.getClassLoader()); + LOGGER.trace(Logging.LOADING, "Completed Automatic event subscribers for {}", getModId()); + } catch (Throwable e) { + LOGGER.error(Logging.LOADING, "Failed to register automatic subscribers. PluginID: {}, class {}", getModId(), this.modClass.getName(), e); + throw new ModLoadingException(this.modInfo, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadmod", e, this.modClass); + } + } + + @Override + public boolean matches(Object mod) { + return mod == this.modInstance; + } + + @Override + public Object getMod() { + return this.modInstance; + } + + @Override + protected void acceptEvent(final T e) { + try { + LOGGER.trace(Logging.LOADING, "Firing event for modid {} : {}", this.getModId(), e); + this.eventBus.post(e); + LOGGER.trace(Logging.LOADING, "Fired event for modid {} : {}", this.getModId(), e); + } catch (Throwable t) { + LOGGER.error(Logging.LOADING, "Caught exception during event {} dispatch for modid {}", e, this.getModId(), t); + throw new ModLoadingException(this.modInfo, this.modLoadingStage, "fml.modloading.errorduringevent", t); + } + } +} diff --git a/neoforge/src/main/java/org/spongepowered/forge/ForgeClient.java b/neoforge/src/main/java/org/spongepowered/forge/ForgeClient.java new file mode 100755 index 00000000000..481345f3c55 --- /dev/null +++ b/neoforge/src/main/java/org/spongepowered/forge/ForgeClient.java @@ -0,0 +1,31 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge; + +import org.spongepowered.common.client.SpongeClient; + +public interface ForgeClient extends ForgeEngine, SpongeClient { + +} diff --git a/neoforge/src/main/java/org/spongepowered/forge/ForgeEngine.java b/neoforge/src/main/java/org/spongepowered/forge/ForgeEngine.java new file mode 100755 index 00000000000..4ca3dfe8832 --- /dev/null +++ b/neoforge/src/main/java/org/spongepowered/forge/ForgeEngine.java @@ -0,0 +1,30 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge; + +import org.spongepowered.common.SpongeEngine; + +public interface ForgeEngine extends SpongeEngine { +} diff --git a/neoforge/src/main/java/org/spongepowered/forge/ForgeServer.java b/neoforge/src/main/java/org/spongepowered/forge/ForgeServer.java new file mode 100755 index 00000000000..d953faf6105 --- /dev/null +++ b/neoforge/src/main/java/org/spongepowered/forge/ForgeServer.java @@ -0,0 +1,34 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge; + +import org.spongepowered.common.SpongeServer; +import org.spongepowered.forge.world.server.ForgeWorldManager; + +public interface ForgeServer extends ForgeEngine, SpongeServer { + + @Override + ForgeWorldManager worldManager(); +} diff --git a/neoforge/src/main/java/org/spongepowered/forge/SpongeAPIMod.java b/neoforge/src/main/java/org/spongepowered/forge/SpongeAPIMod.java new file mode 100755 index 00000000000..dbfdcc9ea0b --- /dev/null +++ b/neoforge/src/main/java/org/spongepowered/forge/SpongeAPIMod.java @@ -0,0 +1,31 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge; + +import net.neoforged.fml.common.Mod; + +@Mod("spongeapi") +public class SpongeAPIMod { +} diff --git a/neoforge/src/main/java/org/spongepowered/forge/SpongeForgeMod.java b/neoforge/src/main/java/org/spongepowered/forge/SpongeForgeMod.java new file mode 100755 index 00000000000..a1e2ba478c9 --- /dev/null +++ b/neoforge/src/main/java/org/spongepowered/forge/SpongeForgeMod.java @@ -0,0 +1,151 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge; + +import net.minecraft.client.Minecraft; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent; +import net.neoforged.neoforge.event.server.ServerAboutToStartEvent; +import net.neoforged.neoforge.event.server.ServerStartedEvent; +import net.neoforged.neoforge.event.server.ServerStoppingEvent; +import net.neoforged.neoforge.registries.RegisterEvent; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.spongepowered.api.Client; +import org.spongepowered.api.Server; +import org.spongepowered.api.Sponge; +import org.spongepowered.common.applaunch.config.core.ConfigHandle; +import org.spongepowered.common.entity.SpongeEntityTypes; +import org.spongepowered.common.entity.living.human.HumanEntity; +import org.spongepowered.common.hooks.PlatformHooks; +import org.spongepowered.common.launch.Launch; +import org.spongepowered.common.launch.Lifecycle; +import org.spongepowered.common.network.channel.SpongeChannelManager; +import org.spongepowered.common.network.packet.SpongePacketHandler; +import org.spongepowered.forge.hook.*; + +@Mod("spongeneoforge") +public final class SpongeForgeMod { + + private final Logger logger = LogManager.getLogger("SpongeNeoForge"); + + public SpongeForgeMod() { + // WorldPersistenceHooks.addHook(SpongeLevelDataPersistence.INSTANCE); // TODO SF 1.19.4 + + final IEventBus modBus = NeoForge.EVENT_BUS; + + // modBus: add all FML events with it + modBus.addListener(this::onCommonSetup); + modBus.addListener(this::onClientSetup); + modBus.addListener(this::onRegister); + modBus.addListener(this::onEntityAttributeCreationEvent); + + // annotation events, for non-FML things + modBus.register(this); + + // Set platform hooks as required + PlatformHooks.INSTANCE.setEventHooks(new ForgeEventHooks()); + PlatformHooks.INSTANCE.setWorldHooks(new ForgeWorldHooks()); + PlatformHooks.INSTANCE.setGeneralHooks(new ForgeGeneralHooks()); + PlatformHooks.INSTANCE.setChannelHooks(new ForgeChannelHooks()); + PlatformHooks.INSTANCE.setItemHooks(new ForgeItemHooks()); + } + + private void onCommonSetup(final FMLCommonSetupEvent event) { + final Lifecycle lifecycle = Launch.instance().lifecycle(); + lifecycle.callConstructEvent(); + lifecycle.callRegisterFactoryEvent(); + lifecycle.callRegisterBuilderEvent(); + lifecycle.callRegisterChannelEvent(); + lifecycle.establishGameServices(); + lifecycle.establishDataKeyListeners(); + + SpongePacketHandler.init((SpongeChannelManager) Sponge.channelManager()); + + this.logger.info("SpongeForge v{} initialized", Launch.instance().platformPlugin().metadata().version()); + } + + private void onClientSetup(final FMLClientSetupEvent event) { + final Client minecraft = (Client) Minecraft.getInstance(); + final Lifecycle lifecycle = Launch.instance().lifecycle(); + lifecycle.establishDataProviders(); + lifecycle.callRegisterDataEvent(); + lifecycle.establishClientRegistries(minecraft); + lifecycle.callStartingEngineEvent(minecraft); + } + + @SubscribeEvent + public void onServerAboutToStart(final ServerAboutToStartEvent event) { + // Save config now that registries have been initialized + ConfigHandle.setSaveSuppressed(false); + + final Lifecycle lifecycle = Launch.instance().lifecycle(); + lifecycle.establishServerServices(); + + lifecycle.establishServerFeatures(); + + lifecycle.establishServerRegistries((Server) event.getServer()); + lifecycle.callStartingEngineEvent((Server) event.getServer()); + } + + @SubscribeEvent + public void onServerStarted(final ServerStartedEvent event) { + final Lifecycle lifecycle = Launch.instance().lifecycle(); + lifecycle.callStartedEngineEvent((Server) event.getServer()); + + lifecycle.callLoadedGameEvent(); + } + + @SubscribeEvent + public void onServerStoppingEvent(final ServerStoppingEvent event) { + final Lifecycle lifecycle = Launch.instance().lifecycle(); + lifecycle.callStoppingEngineEvent((Server) event.getServer()); + } + + public void onRegister(RegisterEvent event) { + if (event.getRegistryKey() == BuiltInRegistries.ENTITY_TYPE) { + SpongeEntityTypes.HUMAN = EntityType.Builder.of(HumanEntity::new, MobCategory.MISC) + .noSave() + .sized(0.6F, 1.8F) + .clientTrackingRange(org.spongepowered.common.util.Constants.Entity.Player.TRACKING_RANGE) + .updateInterval(2) + .build("sponge:human") + ; + + event.register(BuiltInRegistries.ENTITY_TYPE.key(), helper -> helper.register(HumanEntity.KEY, SpongeEntityTypes.HUMAN)); + } + } + public void onEntityAttributeCreationEvent(final EntityAttributeCreationEvent event) { + event.put(SpongeEntityTypes.HUMAN, HumanEntity.createAttributes()); + } +} diff --git a/neoforge/src/main/java/org/spongepowered/forge/SpongeMod.java b/neoforge/src/main/java/org/spongepowered/forge/SpongeMod.java new file mode 100755 index 00000000000..b6524043c06 --- /dev/null +++ b/neoforge/src/main/java/org/spongepowered/forge/SpongeMod.java @@ -0,0 +1,31 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge; + +import net.neoforged.fml.common.Mod; + +@Mod("sponge") +public class SpongeMod { +} diff --git a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeChannelHooks.java b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeChannelHooks.java new file mode 100755 index 00000000000..82e03a96b29 --- /dev/null +++ b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeChannelHooks.java @@ -0,0 +1,59 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.hook; + +import io.netty.buffer.Unpooled; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; +import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; + +import org.spongepowered.api.network.EngineConnectionSide; +import org.spongepowered.api.network.channel.ChannelBuf; +import org.spongepowered.common.hooks.ChannelHooks; +import org.spongepowered.common.network.channel.SpongeChannelPayload; +import org.spongepowered.common.util.Constants; + +import java.util.function.Consumer; + +public final class ForgeChannelHooks implements ChannelHooks { + + @Override + public void registerPlatformChannels(final Consumer> consumer) { + } + + @Override + public Packet createRegisterPayload(final ChannelBuf payload, final EngineConnectionSide side) { + if (side == EngineConnectionSide.CLIENT) { + return ServerboundCustomPayloadPacket.CONFIG_STREAM_CODEC.decode(new FriendlyByteBuf(Unpooled.buffer()).writeResourceLocation((ResourceLocation) (Object) Constants.Channels.REGISTER_KEY).writeBytes(payload.array())); + } else if (side == EngineConnectionSide.SERVER) { + return ClientboundCustomPayloadPacket.CONFIG_STREAM_CODEC.decode(new FriendlyByteBuf(Unpooled.buffer()).writeResourceLocation((ResourceLocation) (Object) Constants.Channels.REGISTER_KEY).writeBytes(payload.array())); + } else { + throw new UnsupportedOperationException(); + } + } +} diff --git a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java new file mode 100755 index 00000000000..681007ddbe2 --- /dev/null +++ b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java @@ -0,0 +1,54 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.hook; + +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack;; +import net.neoforged.neoforge.event.entity.player.CriticalHitEvent; +import org.spongepowered.common.hooks.EventHooks; + +@SuppressWarnings("UnstableApiUsage") +public final class ForgeEventHooks implements EventHooks { + + @Override + public void callItemDestroyedEvent( + final Player player, final ItemStack stack, final InteractionHand hand + ) { + ForgeEventFactory.onPlayerDestroyItem(player, stack, InteractionHand.MAIN_HAND); + } + + @Override + public CriticalHitResult callCriticalHitEvent( + final Player player, final Entity targetEntity, final boolean isCriticalAttack, final float v + ) { + final CriticalHitEvent hitResult = ForgeHooks.getCriticalHit(player, targetEntity, isCriticalAttack, v + 1.0F); + if (hitResult != null) { + return new CriticalHitResult(true, hitResult.getDamageMultiplier() - 1.0F); + } + return new CriticalHitResult(false, v); + } +} diff --git a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeGeneralHooks.java b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeGeneralHooks.java new file mode 100755 index 00000000000..b5e184f002a --- /dev/null +++ b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeGeneralHooks.java @@ -0,0 +1,39 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.hook; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.status.ServerStatus; + +import org.spongepowered.common.hooks.GeneralHooks; + +import java.util.Optional; + +public class ForgeGeneralHooks implements GeneralHooks { + + public ServerStatus createServerStatus(ServerStatus originalStatus, Component description, Optional players, Optional version, Optional favicon) { + return new ServerStatus(description, players, version, favicon, originalStatus.enforcesSecureChat(), originalStatus.isModded()); + } +} diff --git a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeItemHooks.java b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeItemHooks.java new file mode 100755 index 00000000000..7698314caa6 --- /dev/null +++ b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeItemHooks.java @@ -0,0 +1,31 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.hook; + +import org.spongepowered.common.hooks.ItemHooks; + +public class ForgeItemHooks implements ItemHooks { + +} diff --git a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java new file mode 100755 index 00000000000..6da70fbb6e7 --- /dev/null +++ b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java @@ -0,0 +1,66 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.hook; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; + +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.level.LevelEvent; + +import org.spongepowered.common.hooks.WorldHooks; + +public class ForgeWorldHooks implements WorldHooks { + + @Override + public Entity getCustomEntityIfItem(final Entity entity) { + if (entity.getClass().equals(ItemEntity.class)) { + final ItemStack stack = ((ItemEntity) entity).getItem(); + final Item item = stack.getItem(); + if (item.hasCustomEntity(stack)) { + final Entity newEntity = item.createEntity(entity.level(), entity, stack); + if (newEntity != null) { + entity.remove(Entity.RemovalReason.DISCARDED); + return newEntity; + } + } + } + return null; + } + + @Override + public boolean isRestoringBlocks(final Level world) { + return world.restoringBlockSnapshots; + } + + @Override + public void postLoadWorld(final ServerLevel world) { + NeoForge.EVENT_BUS.post(new LevelEvent.Load(world)); + } +} diff --git a/neoforge/src/main/java/org/spongepowered/forge/world/server/ForgeWorldManager.java b/neoforge/src/main/java/org/spongepowered/forge/world/server/ForgeWorldManager.java new file mode 100755 index 00000000000..13c510c27da --- /dev/null +++ b/neoforge/src/main/java/org/spongepowered/forge/world/server/ForgeWorldManager.java @@ -0,0 +1,35 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.world.server; + +import net.minecraft.server.MinecraftServer; +import org.spongepowered.common.world.server.SpongeWorldManager; + +public final class ForgeWorldManager extends SpongeWorldManager { + + public ForgeWorldManager(final MinecraftServer server) { + super(server); + } +} diff --git a/neoforge/src/main/resource-templates/META-INF/mods.toml b/neoforge/src/main/resource-templates/META-INF/mods.toml new file mode 100755 index 00000000000..b6a82ce527b --- /dev/null +++ b/neoforge/src/main/resource-templates/META-INF/mods.toml @@ -0,0 +1,56 @@ +modLoader="javafml" +loaderVersion="[52,)" +license="MIT License" + +issueTrackerURL="https://github.com/SpongePowered/Sponge/issues" + + +[[mods]] +modId="spongeforge" +version="{{ version }}" +displayName="SpongeForge" +displayTest="IGNORE_SERVER_VERSION" +credits="SpongePowered and Contributors" +authors="SpongePowered" +description = "{{ description }}" + +[[dependencies.spongeforge]] +modId="forge" +mandatory=true +versionRange="[52,)" +ordering="AFTER" +side="BOTH" + +[[dependencies.spongeforge]] +modId="sponge" +mandatory=true +versionRange="[{{ version }}]" +ordering="AFTER" +side="BOTH" + + +[[mods]] +modId="sponge" +version="{{ version }}" +displayName="Sponge" +displayTest="IGNORE_SERVER_VERSION" +credits="SpongePowered and Contributors" +authors="SpongePowered" +description="The SpongeAPI implementation targeting vanilla Minecraft and 3rd party platforms" + +[[dependencies.sponge]] +modId="spongeapi" +mandatory=true +versionRange="[12.0.0,)" +ordering="AFTER" +side="BOTH" + + +[[mods]] +modId="spongeapi" +version="12.0.0" +displayName="SpongeAPI" +displayTest="IGNORE_SERVER_VERSION" +credits="SpongePowered and Contributors" +authors="SpongePowered" +description="A Minecraft plugin API" diff --git a/neoforge/src/main/resources/forge.superclasschange b/neoforge/src/main/resources/forge.superclasschange new file mode 100755 index 00000000000..d6e2705c885 --- /dev/null +++ b/neoforge/src/main/resources/forge.superclasschange @@ -0,0 +1,3 @@ +{ + "org.spongepowered.api.entity.ai.goal.AbstractGoal": "net.minecraft.world.entity.ai.goal.Goal" +} \ No newline at end of file diff --git a/neoforge/src/main/resources/pack.mcmeta b/neoforge/src/main/resources/pack.mcmeta new file mode 100755 index 00000000000..da6cf4608c3 --- /dev/null +++ b/neoforge/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "Resources for SpongeForge", + "pack_format": 34 + } +} \ No newline at end of file diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/api/minecraft/server/MinecraftServerMixin_Forge_API.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/api/minecraft/server/MinecraftServerMixin_Forge_API.java new file mode 100755 index 00000000000..21feb542317 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/api/minecraft/server/MinecraftServerMixin_Forge_API.java @@ -0,0 +1,49 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.api.minecraft.server; + +import net.minecraft.server.MinecraftServer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.forge.ForgeServer; +import org.spongepowered.forge.world.server.ForgeWorldManager; + +@Mixin(MinecraftServer.class) +public abstract class MinecraftServerMixin_Forge_API implements ForgeServer { + + private ForgeWorldManager forgeAPI$worldManager; + + @Inject(method = "", at = @At("TAIL")) + private void forgeAPI$setupSpongeFields(CallbackInfo ci) { + this.forgeAPI$worldManager = new ForgeWorldManager((MinecraftServer) (Object) this); + } + + @Override + public ForgeWorldManager worldManager() { + return this.forgeAPI$worldManager; + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/EventMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/EventMixin_Forge.java new file mode 100755 index 00000000000..475f7c6bf71 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/EventMixin_Forge.java @@ -0,0 +1,34 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.api.event; + +import org.spongepowered.api.event.Event; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.forge.launch.bridge.event.SpongeEventBridge_Forge; + +@Mixin(value = Event.class, remap = false) +public interface EventMixin_Forge extends SpongeEventBridge_Forge { + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/block/ChangeBlockEvent_AllMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/block/ChangeBlockEvent_AllMixin_Forge.java new file mode 100755 index 00000000000..d9ad83e55f4 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/block/ChangeBlockEvent_AllMixin_Forge.java @@ -0,0 +1,66 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.api.event.block; + +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.event.level.BlockEvent; +import net.minecraftforge.eventbus.api.Event; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.api.block.transaction.BlockTransaction; +import org.spongepowered.api.block.transaction.Operation; +import org.spongepowered.api.block.transaction.Operations; +import org.spongepowered.api.event.block.ChangeBlockEvent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.common.util.VecHelper; +import org.spongepowered.forge.launch.bridge.event.SpongeEventBridge_Forge; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +@Mixin(value = ChangeBlockEvent.All.class, remap = false) +public interface ChangeBlockEvent_AllMixin_Forge extends SpongeEventBridge_Forge { + + @Override + default @Nullable Collection bridge$createForgeEvents() { + final ChangeBlockEvent.All thisEvent = ((ChangeBlockEvent.All) this); + final Player player = thisEvent.cause().first(Player.class).orElse(null); + final Operation breakOp = Operations.BREAK.get(); + + final List forgeEvents = new ArrayList<>(); + for (final BlockTransaction transaction : thisEvent.transactions()) { + if (player != null && transaction.operation() == breakOp) { + forgeEvents.add(new BlockEvent.BreakEvent((Level) thisEvent.world(), + VecHelper.toBlockPos(transaction.original().position()), + (BlockState) transaction.original().state(), player)); + } + // TODO: Other event types may go here - break is a PoC. + } + return forgeEvents; + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEntityWorldEvent_PreMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEntityWorldEvent_PreMixin_Forge.java new file mode 100755 index 00000000000..30a236eefe4 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEntityWorldEvent_PreMixin_Forge.java @@ -0,0 +1,49 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.api.event.entity; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraftforge.event.entity.EntityTravelToDimensionEvent; +import net.minecraftforge.eventbus.api.Event; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.api.event.entity.ChangeEntityWorldEvent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.forge.mixin.core.api.event.EventMixin_Forge; + +import java.util.Collection; +import java.util.Collections; + +@Mixin(ChangeEntityWorldEvent.Pre.class) +public interface ChangeEntityWorldEvent_PreMixin_Forge extends EventMixin_Forge { + + @Override + default @Nullable Collection bridge$createForgeEvents() { + final ChangeEntityWorldEvent.Pre thisEvent = (ChangeEntityWorldEvent.Pre) this; + return Collections.singleton( + new EntityTravelToDimensionEvent((Entity) thisEvent.entity(), ((ServerLevel) thisEvent.destinationWorld()).dimension())); + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEventWorldEvent_PostMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEventWorldEvent_PostMixin_Forge.java new file mode 100755 index 00000000000..f85995d0727 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEventWorldEvent_PostMixin_Forge.java @@ -0,0 +1,53 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.api.event.entity; + +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.eventbus.api.Event; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.api.event.entity.ChangeEntityWorldEvent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.forge.mixin.core.api.event.EventMixin_Forge; + +import java.util.Collection; +import java.util.Collections; + +@Mixin(ChangeEntityWorldEvent.Post.class) +public interface ChangeEventWorldEvent_PostMixin_Forge extends EventMixin_Forge { + + @Override + default @Nullable Collection bridge$createForgeEvents() { + if (((ChangeEntityWorldEvent.Post) this).entity() instanceof ServerPlayer) { + final ServerPlayer player = (ServerPlayer) ((ChangeEntityWorldEvent.Post) this).entity(); + + return Collections.singletonList(new PlayerEvent.PlayerChangedDimensionEvent(player, + ((ServerLevel) ((ChangeEntityWorldEvent.Post) this).originalWorld()).dimension(), + ((ServerLevel) ((ChangeEntityWorldEvent.Post) this).destinationWorld()).dimension())); + } + return null; + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/MinecraftMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/MinecraftMixin_Forge.java new file mode 100755 index 00000000000..1ea4074660c --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/MinecraftMixin_Forge.java @@ -0,0 +1,40 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.client; + +import net.minecraft.client.Minecraft; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.common.bridge.client.MinecraftBridge; +import org.spongepowered.common.entity.player.ClientType; +import org.spongepowered.forge.ForgeClient; + +@Mixin(Minecraft.class) +public abstract class MinecraftMixin_Forge implements ForgeClient, MinecraftBridge { + + @Override + public ClientType bridge$getClientType() { + return ClientType.SPONGE_FORGE; + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/main/MainMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/main/MainMixin_Forge.java new file mode 100755 index 00000000000..d98d8d5bb53 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/main/MainMixin_Forge.java @@ -0,0 +1,50 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.client.main; + +import net.minecraft.client.main.Main; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.common.applaunch.AppLaunch; +import org.spongepowered.common.applaunch.plugin.PluginPlatform; +import org.spongepowered.common.launch.Launch; +import org.spongepowered.forge.launch.ForgeLaunch; + +@Mixin(Main.class) +public abstract class MainMixin_Forge { + + @Inject(method = "", at = @At("RETURN")) + private static void forge$initLaunch(final CallbackInfo ci) { + if (Launch.instance() != null) { + return; + } + final PluginPlatform pluginPlatform = AppLaunch.pluginPlatform(); + final ForgeLaunch launch = new ForgeLaunch(pluginPlatform); + Launch.setInstance(launch); + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/commands/CommandsMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/commands/CommandsMixin_Forge.java new file mode 100755 index 00000000000..94dbf3edd68 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/commands/CommandsMixin_Forge.java @@ -0,0 +1,101 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.commands; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.suggestion.SuggestionProvider; +import com.mojang.brigadier.tree.CommandNode; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.commands.SharedSuggestionProvider; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.eventbus.api.Event; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.server.command.CommandHelper; +import org.spongepowered.api.command.CommandCause; +import org.spongepowered.api.event.CauseStackManager; +import org.spongepowered.api.event.EventContextKeys; +import org.spongepowered.api.service.permission.Subject; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.common.bridge.commands.CommandSourceStackBridge; +import org.spongepowered.common.command.manager.SpongeCommandManager; +import org.spongepowered.common.event.tracking.PhaseTracker; + +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.function.Function; + +@Mixin(Commands.class) +public abstract class CommandsMixin_Forge { + + private WeakHashMap, List>>> impl$playerNodeCache; + private SpongeCommandManager impl$commandManager; + + // The event fired by Forge is fired in SpongeForgeCommandManager at the appropriate time. + @Redirect(method = "performCommand", + at = @At(value = "INVOKE", target = "Lnet/minecraftforge/eventbus/api/IEventBus;post(Lnet/minecraftforge/eventbus/api/Event;)Z")) + private boolean forge$redirectToSpongeCommandManager(IEventBus instance, Event event) { + return false; + } + + + @SuppressWarnings("unchecked") + @Redirect(method = "sendCommands", at = @At( + value = "INVOKE", + target = "Lnet/minecraftforge/server/command/CommandHelper;mergeCommandNode(Lcom/mojang/brigadier/tree/CommandNode;Lcom/mojang/brigadier/tree/CommandNode;Ljava/util/Map;Ljava/lang/Object;Lcom/mojang/brigadier/Command;Ljava/util/function/Function;)V", + remap = false + )) + private void impl$addNonBrigSuggestions( + final CommandNode sourceChild, + final CommandNode sourceNode, + final Map, CommandNode> resultNode, + final S sourceToResult, + final Command canUse, + final Function, SuggestionProvider> execute, + final ServerPlayer player + ) { + try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) { + frame.pushCause(player); + frame.addContext(EventContextKeys.SUBJECT, (Subject) player); + final CommandCause sourceToUse = ((CommandSourceStackBridge) sourceToResult).bridge$withCurrentCause(); + try { + this.impl$playerNodeCache.put(player, new IdentityHashMap<>()); + // We use this because the redirects should be a 1:1 mapping (which is what this map is for). + final IdentityHashMap, CommandNode> idMap = new IdentityHashMap<>(resultNode); + CommandHelper.mergeCommandNode(sourceChild, sourceNode, idMap, sourceToResult, canUse, execute); + } finally { + this.impl$playerNodeCache.remove(player); + } + for (final CommandNode node : this.impl$commandManager.getNonBrigadierSuggestions(sourceToUse)) { + sourceNode.addChild((CommandNode) node); + } + } + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/MinecraftForgeMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/MinecraftForgeMixin_Forge.java new file mode 100755 index 00000000000..536ca09e693 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/MinecraftForgeMixin_Forge.java @@ -0,0 +1,46 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.minecraftforge; + +import net.neoforged.bus.BusBuilderImpl; +import net.neoforged.bus.api.BusBuilder; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.common.NeoForge; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.forge.launch.event.ForgeEventManager; +import org.spongepowered.forge.launch.event.SpongeEventBus; + +@Mixin(NeoForge.class) +public abstract class MinecraftForgeMixin_Forge { + + @Redirect(method = "", at = @At(value = "INVOKE", + target = "Lnet/neoforged/bus/api/BusBuilder;build()Lnet/neoforged/bus/api/IEventBus;", remap = false)) + private static IEventBus forge$substituteForgeEventBus(final BusBuilder builder) { + return new ForgeEventManager(new SpongeEventBus((BusBuilderImpl) builder)); + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/EntityTravelToDimensionEventMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/EntityTravelToDimensionEventMixin_Forge.java new file mode 100755 index 00000000000..bb964ccbbfe --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/EntityTravelToDimensionEventMixin_Forge.java @@ -0,0 +1,76 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.minecraftforge.event.entity; + +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; +import net.minecraftforge.event.entity.EntityEvent; +import net.minecraftforge.event.entity.EntityTravelToDimensionEvent; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.api.event.Event; +import org.spongepowered.api.event.SpongeEventFactory; +import org.spongepowered.api.event.entity.ChangeEntityWorldEvent; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.common.SpongeCommon; +import org.spongepowered.common.event.tracking.PhaseTracker; +import org.spongepowered.forge.launch.bridge.event.ForgeEventBridge_Forge; + +@Mixin(value = EntityTravelToDimensionEvent.class, remap = false) +public abstract class EntityTravelToDimensionEventMixin_Forge implements ForgeEventBridge_Forge { + + // @formatter:off + @Shadow @Final @Mutable private ResourceKey dimension; + // @formatter:on + + @Override + public void bridge$syncFrom(final Event event) { + if (event instanceof ChangeEntityWorldEvent.Pre) { + ((net.minecraftforge.eventbus.api.Event) (Object) this).setCanceled(((ChangeEntityWorldEvent.Pre) event).isCancelled()); + this.dimension = ((ServerLevel) ((ChangeEntityWorldEvent.Pre) event).destinationWorld()).dimension(); + } + } + + @Override + public void bridge$syncTo(final Event event) { + if (event instanceof ChangeEntityWorldEvent.Pre) { + ((ChangeEntityWorldEvent.Pre) event).setCancelled(((net.minecraftforge.eventbus.api.Event) (Object) this).isCanceled()); + } + } + + @Override + public @Nullable Event bridge$createSpongeEvent() { + final Entity entity = ((EntityEvent) (Object) this).getEntity(); + final ServerLevel toWorld = SpongeCommon.server().getLevel(this.dimension); + return SpongeEventFactory.createChangeEntityWorldEventPre(PhaseTracker.getCauseStackManager().currentCause(), + (org.spongepowered.api.entity.Entity) entity, (org.spongepowered.api.world.server.ServerWorld) entity.getCommandSenderWorld(), + (org.spongepowered.api.world.server.ServerWorld) toWorld, (org.spongepowered.api.world.server.ServerWorld) toWorld); + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/player/PlayerEvent_PlayerChangedDimensionEventMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/player/PlayerEvent_PlayerChangedDimensionEventMixin_Forge.java new file mode 100755 index 00000000000..f7490394fde --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/player/PlayerEvent_PlayerChangedDimensionEventMixin_Forge.java @@ -0,0 +1,72 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.minecraftforge.event.entity.player; + +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.Level; +import net.minecraftforge.event.entity.player.PlayerEvent; +import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.event.Event; +import org.spongepowered.api.event.SpongeEventFactory; +import org.spongepowered.api.world.server.ServerWorld; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.common.SpongeCommon; +import org.spongepowered.common.event.tracking.PhaseTracker; +import org.spongepowered.forge.launch.bridge.event.ForgeEventBridge_Forge; + +@Mixin(value = PlayerEvent.PlayerChangedDimensionEvent.class, remap = false) +public final class PlayerEvent_PlayerChangedDimensionEventMixin_Forge implements ForgeEventBridge_Forge { + + // @formatter:off + @Shadow @Final private ResourceKey fromDim; + @Shadow @Final private ResourceKey toDim; + // @formatter:on + + @Override + public void bridge$syncFrom(final Event event) { + // nothing to do -- informational only + } + + @Override + public void bridge$syncTo(final Event event) { + // nothing to do -- informational only + } + + @SuppressWarnings("ConstantConditions") + @Override + public Event bridge$createSpongeEvent() { + final PlayerEvent.PlayerChangedDimensionEvent thisEvent = (PlayerEvent.PlayerChangedDimensionEvent) (Object) this; + return SpongeEventFactory.createChangeEntityWorldEventPost( + PhaseTracker.getCauseStackManager().currentCause(), + (Entity) thisEvent.getEntity(), + (ServerWorld) SpongeCommon.server().getLevel(this.fromDim), + (ServerWorld) SpongeCommon.server().getLevel(this.toDim), + (ServerWorld) SpongeCommon.server().getLevel(this.toDim) + ); + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEventMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEventMixin_Forge.java new file mode 100755 index 00000000000..166b9201a39 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEventMixin_Forge.java @@ -0,0 +1,43 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.minecraftforge.event.world; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.event.level.BlockEvent; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(value = BlockEvent.class, remap = false) +public abstract class BlockEventMixin_Forge { + + // @formatter:off + @Shadow public abstract LevelAccessor shadow$getLevel(); + @Shadow public abstract BlockPos shadow$getPos(); + @Shadow public abstract BlockState shadow$getState(); + // @formatter:on + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEvent_BreakEventMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEvent_BreakEventMixin_Forge.java new file mode 100755 index 00000000000..55845d3e685 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEvent_BreakEventMixin_Forge.java @@ -0,0 +1,99 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.minecraftforge.event.world; + +import net.minecraft.world.level.LevelAccessor; +import net.minecraftforge.event.level.BlockEvent; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.api.block.BlockState; +import org.spongepowered.api.block.BlockTypes; +import org.spongepowered.api.block.transaction.BlockTransaction; +import org.spongepowered.api.block.transaction.Operations; +import org.spongepowered.api.event.Event; +import org.spongepowered.api.event.SpongeEventFactory; +import org.spongepowered.api.event.block.ChangeBlockEvent; +import org.spongepowered.api.world.server.ServerWorld; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.common.block.SpongeBlockSnapshot; +import org.spongepowered.common.event.tracking.PhaseTracker; +import org.spongepowered.common.util.VecHelper; +import org.spongepowered.forge.launch.bridge.event.ForgeEventBridge_Forge; +import org.spongepowered.math.vector.Vector3i; + +import java.util.Collections; + +@Mixin(value = BlockEvent.BreakEvent.class, remap = false) +public abstract class BlockEvent_BreakEventMixin_Forge extends BlockEventMixin_Forge implements ForgeEventBridge_Forge { + + @Override + public void bridge$syncFrom(final Event event) { + if (event instanceof ChangeBlockEvent.All) { + final ChangeBlockEvent.All changeBlockEventAll = (ChangeBlockEvent.All) event; + final Vector3i pos = VecHelper.toVector3i(this.shadow$getPos()); + if (changeBlockEventAll.isCancelled() || + changeBlockEventAll.transactions() + .stream() + .filter(x -> x.original().position().equals(pos)) + .anyMatch(x -> !x.isValid() || x.operation() != Operations.BREAK.get() || x.custom().isPresent())) { + ((net.minecraftforge.eventbus.api.Event) (Object) this).setCanceled(true); + } + } + } + + @Override + public void bridge$syncTo(final Event event) { + if (event instanceof ChangeBlockEvent.All && ((net.minecraftforge.eventbus.api.Event) (Object) this).isCanceled()) { + final Vector3i pos = VecHelper.toVector3i(this.shadow$getPos()); + ((ChangeBlockEvent.All) event).transactions(Operations.BREAK.get()).filter(x -> x.original().position().equals(pos)) + .forEach(x -> x.setValid(false)); + } + } + + @Override + public @Nullable Event bridge$createSpongeEvent() { + final LevelAccessor accessor = this.shadow$getLevel(); + if (accessor instanceof ServerWorld) { + final ServerWorld serverWorld = (ServerWorld) accessor; + final BlockTransaction transaction = new BlockTransaction( + SpongeBlockSnapshot.BuilderImpl + .pooled() + .world(serverWorld.key()) + .position(VecHelper.toVector3i(this.shadow$getPos())) + .blockState((BlockState) this.shadow$getState()) + .build(), + SpongeBlockSnapshot.BuilderImpl + .pooled() + .world(serverWorld.key()) + .position(VecHelper.toVector3i(this.shadow$getPos())) + .blockState(BlockState.builder().blockType(BlockTypes.AIR.get()).build()) + .build(), + Operations.BREAK.get() + ); + return SpongeEventFactory.createChangeBlockEventAll(PhaseTracker.getCauseStackManager().currentCause(), + Collections.singletonList(transaction), serverWorld); + } + return null; + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/internal/BrandingControlMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/internal/BrandingControlMixin_Forge.java new file mode 100755 index 00000000000..841f6ba78ea --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/internal/BrandingControlMixin_Forge.java @@ -0,0 +1,51 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.minecraftforge.internal; + +import net.minecraftforge.internal.BrandingControl; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +@Mixin(value = BrandingControl.class, remap = false) +public abstract class BrandingControlMixin_Forge { + + /** + * @author Zidane + * @reason This is also not Kansas anymore + */ + @Overwrite + public static String getClientBranding() { + return "forge/spongeforge"; + } + + /** + * @author Zidane + * @reason What that said above + */ + @Overwrite + public static String getServerBranding() { + return "forge/spongeforge"; + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/ForgeRegistryMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/ForgeRegistryMixin_Forge.java new file mode 100755 index 00000000000..d382d4bd688 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/ForgeRegistryMixin_Forge.java @@ -0,0 +1,88 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.minecraftforge.registries; + +import com.google.common.collect.Maps; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.IForgeRegistry; +import org.spongepowered.api.ResourceKey; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.common.SpongeCommon; +import org.spongepowered.common.bridge.core.RegistryBridge; +import org.spongepowered.common.registry.SpongeRegistryEntry; +import org.spongepowered.common.registry.SpongeRegistryType; + +import java.util.Map; +import java.util.StringJoiner; + +@Mixin(ForgeRegistry.class) +public abstract class ForgeRegistryMixin_Forge { + + // @formatter:off + @Shadow @Final private net.minecraft.resources.ResourceKey> key; + // @formatter:on + + private final Map> forge$parents = Maps.newHashMap(); + private boolean forge$warnedIfNoParent; + + @Inject(method = "add(ILnet/minecraft/resources/ResourceLocation;Ljava/lang/Object;Ljava/lang/String;)I", at = @At("TAIL")) + public void forge$writeToParent(final int id, final ResourceLocation key, final V value, final String owner, final CallbackInfoReturnable cir) { + final ResourceKey root = (ResourceKey) (Object) this.key.registry(); + final ResourceKey location = (ResourceKey) (Object) this.key.location(); + + if (!this.forge$warnedIfNoParent && this.forge$parents.isEmpty()) { + // We only care about minecraft namespaced registries, as that is what we've got parents for. + if (location.namespace().equalsIgnoreCase("minecraft")) { + SpongeCommon.logger().error(String.format( + "No parent registry found for %s, things might not work correctly!", + new StringJoiner("/").add(root.formatted()).add(location.formatted()) + )); + } + this.forge$warnedIfNoParent = true; + } + + final SpongeRegistryEntry entry = new SpongeRegistryEntry<>(new SpongeRegistryType<>(root, location), + (ResourceKey) (Object) key, value); + + this.forge$parents.values().forEach(registry -> registry.bridge$register(entry)); + } + + @SuppressWarnings("unchecked") + @Inject(method = "setSlaveMap", at = @At("TAIL")) + public void forge$establishParent(final IForgeRegistry.SlaveKey key, final Object obj, final CallbackInfo ci) { + if (obj instanceof RegistryBridge) { + this.forge$parents.put((ResourceKey) (Object) key.name(), (RegistryBridge) obj); + } + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/RegistryManagerMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/RegistryManagerMixin_Forge.java new file mode 100755 index 00000000000..f591b0f1463 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/RegistryManagerMixin_Forge.java @@ -0,0 +1,51 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.minecraftforge.registries; + +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.RegistryManager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Map; + +@Mixin(RegistryManager.class) +public class RegistryManagerMixin_Forge { + + @SuppressWarnings("UnstableApiUsage") + @Inject(method = "takeSnapshot", at = @At("RETURN")) + public void forge$dontSendSpongeDataToClient(boolean savingToDisc, CallbackInfoReturnable> cir) { + if (savingToDisc) { + return; + } + + for (ForgeRegistry.Snapshot snapshot : cir.getReturnValue().values()) { + snapshot.ids.keySet().removeIf(loc -> loc.getNamespace().equals("sponge")); + } + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/network/ConnectionMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/network/ConnectionMixin_Forge.java new file mode 100755 index 00000000000..ed066933318 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/network/ConnectionMixin_Forge.java @@ -0,0 +1,46 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.network; + +import io.netty.util.concurrent.Future; +import net.minecraft.network.Connection; +import net.minecraft.network.PacketSendListener; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.common.network.channel.PacketSender; + +@Mixin(Connection.class) +public abstract class ConnectionMixin_Forge { + + @Inject(method = "lambda$doSendPacket$15", at = @At(value = "INVOKE", target = "Lio/netty/util/concurrent/Future;isSuccess()Z")) + public void impl$onPacketSent(final PacketSendListener listener, final Future future, final CallbackInfo ci) { + if (listener instanceof final PacketSender.SpongePacketSendListener spongeListener) { + spongeListener.accept(future.cause()); + } + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/BootstrapMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/BootstrapMixin_Forge.java new file mode 100755 index 00000000000..d999fb6f0e9 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/BootstrapMixin_Forge.java @@ -0,0 +1,62 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.server; + +import com.google.inject.Injector; +import com.google.inject.Stage; +import net.minecraft.server.Bootstrap; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.common.SpongeCommon; +import org.spongepowered.common.SpongeLifecycle; +import org.spongepowered.common.inject.SpongeGuice; +import org.spongepowered.common.launch.Launch; +import org.spongepowered.forge.launch.ForgeLaunch; + +@Mixin(Bootstrap.class) +public abstract class BootstrapMixin_Forge { + + // @formatter:off + @Shadow private static boolean isBootstrapped; + // @formatter:on + + @Inject(method = "bootStrap", at = @At("HEAD")) + private static void forge$startLifecycle(final CallbackInfo ci) { + if (BootstrapMixin_Forge.isBootstrapped) { + return; + } + final ForgeLaunch launch = Launch.instance(); + final Stage stage = SpongeGuice.getInjectorStage(launch.injectionStage()); + SpongeCommon.logger().debug("Creating injector in stage '{}'", stage); + final Injector bootstrapInjector = launch.createInjector(); + final SpongeLifecycle lifecycle = bootstrapInjector.getInstance(SpongeLifecycle.class); + launch.setLifecycle(lifecycle); + lifecycle.establishFactories(); + lifecycle.establishBuilders(); + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MainMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MainMixin_Forge.java new file mode 100755 index 00000000000..46b233af9ee --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MainMixin_Forge.java @@ -0,0 +1,46 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.server; + +import net.minecraft.server.Main; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.common.applaunch.AppLaunch; +import org.spongepowered.common.applaunch.plugin.PluginPlatform; +import org.spongepowered.common.launch.Launch; +import org.spongepowered.forge.launch.ForgeLaunch; + +@Mixin(Main.class) +public abstract class MainMixin_Forge { + + @Inject(method = "", at = @At("RETURN")) + private static void forge$initLaunch(final CallbackInfo ci) { + final PluginPlatform pluginPlatform = AppLaunch.pluginPlatform(); + final ForgeLaunch launch = new ForgeLaunch(pluginPlatform); + Launch.setInstance(launch); + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MinecraftServerMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MinecraftServerMixin_Forge.java new file mode 100755 index 00000000000..d64d8c83bd5 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MinecraftServerMixin_Forge.java @@ -0,0 +1,53 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.server; + +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.common.bridge.server.level.ServerLevelBridge; +import org.spongepowered.forge.ForgeServer; + +@Mixin(MinecraftServer.class) +public abstract class MinecraftServerMixin_Forge implements ForgeServer { + + // @formatter:off + @Shadow @Nullable public abstract ServerLevel shadow$getLevel(ResourceKey p_71218_1_); + // @formatter:on + + /** + * @author Zidane + * @reason We store the per-world tick time on the ServerLevel itself to more accurately track this. + */ + @Overwrite(remap = false) + public long[] getTickTime(ResourceKey dim) { + return ((ServerLevelBridge) this.shadow$getLevel(dim)).bridge$recentTickTimes(); + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/commands/SpreadPlayersCommandMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/commands/SpreadPlayersCommandMixin_Forge.java new file mode 100755 index 00000000000..94adf0c914b --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/commands/SpreadPlayersCommandMixin_Forge.java @@ -0,0 +1,53 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.server.commands; + +import net.minecraft.server.commands.SpreadPlayersCommand; +import net.minecraft.world.entity.Entity; +import net.minecraftforge.event.ForgeEventFactory; +import net.minecraftforge.event.entity.EntityTeleportEvent; +import org.spongepowered.api.event.CauseStackManager; +import org.spongepowered.api.event.EventContextKeys; +import org.spongepowered.api.event.cause.entity.MovementTypes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.common.event.tracking.PhaseTracker; + +@Mixin(SpreadPlayersCommand.class) +public abstract class SpreadPlayersCommandMixin_Forge { + + @Redirect(method = "setPlayerPositions", at = @At( + value = "INVOKE", + target = "Lnet/minecraftforge/event/ForgeEventFactory;onEntityTeleportSpreadPlayersCommand(Lnet/minecraft/world/entity/Entity;DDD)Lnet/minecraftforge/event/entity/EntityTeleportEvent$SpreadPlayersCommand;" + )) + private static EntityTeleportEvent.SpreadPlayersCommand vanilla$createCauseFrameForTeleport(Entity entity, double targetX, double targetY, double targetZ) { + try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) { + frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND); + + return ForgeEventFactory.onEntityTeleportSpreadPlayersCommand(entity, targetX, targetY, targetZ); + } + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/level/ServerPlayerMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/level/ServerPlayerMixin_Forge.java new file mode 100755 index 00000000000..b06f9cb2cce --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/level/ServerPlayerMixin_Forge.java @@ -0,0 +1,51 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.server.level; + +import net.minecraft.server.level.ServerPlayer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.common.event.tracking.PhaseContext; +import org.spongepowered.common.event.tracking.PhaseTracker; +import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor; +import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier; +import org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction; +import org.spongepowered.forge.mixin.core.world.entity.LivingEntityMixin_Forge; + +@Mixin(ServerPlayer.class) +public abstract class ServerPlayerMixin_Forge extends LivingEntityMixin_Forge { + + // override from LivingEntityMixin_Forge + @Override + protected void forge$onElytraUse(final CallbackInfo ci) { + final PhaseContext context = PhaseTracker.SERVER.getPhaseContext(); + final TransactionalCaptureSupplier transactor = context.getTransactor(); + final net.minecraft.server.level.ServerPlayer player = (net.minecraft.server.level.ServerPlayer) (Object) this; + try (final EffectTransactor ignored = transactor.logPlayerInventoryChangeWithEffect(player, PlayerInventoryTransaction.EventCreator.STANDARD)) { + player.inventoryMenu.broadcastChanges(); // capture + } + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerGamePacketListenerImplMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerGamePacketListenerImplMixin_Forge.java new file mode 100755 index 00000000000..f8e9a9a30af --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerGamePacketListenerImplMixin_Forge.java @@ -0,0 +1,66 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.server.network; + +import net.minecraft.network.protocol.game.ServerGamePacketListener; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.world.inventory.RecipeBookMenu; +import net.minecraft.world.item.crafting.RecipeHolder; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.spongepowered.api.item.inventory.Inventory; +import org.spongepowered.api.item.inventory.crafting.CraftingInventory; +import org.spongepowered.api.item.inventory.query.QueryTypes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.common.SpongeCommon; +import org.spongepowered.common.event.tracking.PhaseContext; +import org.spongepowered.common.event.tracking.PhaseTracker; +import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor; +import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier; + +@Mixin(ServerGamePacketListenerImpl.class) +public abstract class ServerGamePacketListenerImplMixin_Forge implements ServerGamePacketListener { + + @SuppressWarnings({"unchecked", "rawtypes"}) + @Redirect(method = "lambda$handlePlaceRecipe$10", + at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/RecipeBookMenu;handlePlacement(ZLnet/minecraft/world/item/crafting/RecipeHolder;Lnet/minecraft/server/level/ServerPlayer;)V")) + private void forge$onPlaceRecipe(final RecipeBookMenu recipeBookMenu, final boolean shift, final RecipeHolder recipe, final net.minecraft.server.level.ServerPlayer player) { + final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext(); + final TransactionalCaptureSupplier transactor = context.getTransactor(); + + final Inventory craftInv = ((Inventory) player.containerMenu).query(QueryTypes.INVENTORY_TYPE.get().of(CraftingInventory.class)); + if (!(craftInv instanceof CraftingInventory)) { + recipeBookMenu.handlePlacement(shift, recipe, player); + SpongeCommon.logger().warn("Detected crafting without a InventoryCrafting!? Crafting Event will not fire."); + return; + } + + try (final EffectTransactor ignored = transactor.logPlaceRecipe(shift, recipe, player, (CraftingInventory) craftInv)) { + recipeBookMenu.handlePlacement(shift, recipe, player); + player.containerMenu.broadcastChanges(); + } + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerLoginPacketListenerImplMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerLoginPacketListenerImplMixin_Forge.java new file mode 100755 index 00000000000..38fdc9aaff5 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerLoginPacketListenerImplMixin_Forge.java @@ -0,0 +1,50 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.server.network; + +import net.minecraft.network.protocol.login.ServerLoginPacketListener; +import net.minecraft.server.network.ServerLoginPacketListenerImpl; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.common.bridge.network.ServerLoginPacketListenerImplBridge; + +@Mixin(ServerLoginPacketListenerImpl.class) +public abstract class ServerLoginPacketListenerImplMixin_Forge implements ServerLoginPacketListener, ServerLoginPacketListenerImplBridge { + + // @formatter:off + @Shadow private ServerLoginPacketListenerImpl.State state; + // @formatter:on + + @Inject(method = "tick", at = @At("HEAD")) + private void impl$onTick(final CallbackInfo ci) { + // In SpongeVanilla we do channel registration during this state, not sure if we need to do anything in SpongeForge + if (this.state == ServerLoginPacketListenerImpl.State.NEGOTIATING) { + this.state = ServerLoginPacketListenerImpl.State.VERIFYING; + } + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge.java new file mode 100755 index 00000000000..819262550c7 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge.java @@ -0,0 +1,64 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.world.entity; + +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.LivingEntity; +import net.minecraftforge.common.ForgeHooks; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.common.bridge.world.entity.PlatformLivingEntityBridge; + +@Mixin(value = LivingEntity.class) +public abstract class LivingEntityMixin_Forge implements PlatformLivingEntityBridge { + + @Inject( + method = "updateFallFlying", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/item/ItemStack;elytraFlightTick(Lnet/minecraft/world/entity/LivingEntity;I)Z", + shift = At.Shift.AFTER + ) + ) + protected void forge$onElytraUse(final CallbackInfo ci) { + } + + @Override + public boolean bridge$onLivingAttack(final LivingEntity entity, final DamageSource source, final float amount) { + return ForgeHooks.onLivingAttack(entity, source, amount); + } + + @Override + public float bridge$applyModDamage(final LivingEntity entity, final DamageSource source, final float damage) { + return ForgeHooks.onLivingHurt(entity, source, damage); + } + + @Override + public float bridge$applyModDamageBeforeFunctions(final LivingEntity entity, final DamageSource source, final float damage) { + return ForgeHooks.onLivingDamage(entity, source, damage); + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge_Attack_Impl.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge_Attack_Impl.java new file mode 100755 index 00000000000..1cb83895595 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge_Attack_Impl.java @@ -0,0 +1,46 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.world.entity; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.stats.Stat; +import net.minecraft.world.entity.LivingEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(LivingEntity.class) +public class LivingEntityMixin_Forge_Attack_Impl { + + /** + * Prevents {@link ServerPlayer#awardStat} from running before event + */ + @Redirect(method = "getDamageAfterMagicAbsorb", + at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;awardStat(Lnet/minecraft/stats/Stat;I)V")) + public void attackImpl$onAwardStatDamageResist(final ServerPlayer instance, final Stat resourceLocation, final int i) { + // do nothing + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/item/ItemEntityMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/item/ItemEntityMixin_Forge.java new file mode 100755 index 00000000000..1ad9b4ed978 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/item/ItemEntityMixin_Forge.java @@ -0,0 +1,53 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.world.entity.item; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.common.config.SpongeGameConfigs; + +@Mixin(ItemEntity.class) +public abstract class ItemEntityMixin_Forge { + + // @formatter:off + @Shadow public int lifespan; + // @formatter:on + + @Inject(method = "(Lnet/minecraft/world/entity/EntityType;Lnet/minecraft/world/level/Level;)V", at = @At("RETURN")) + private void forge$setLifespanFromConfig(final EntityType type, final Level level, + final CallbackInfo ci + ) { + // Check the level is not null to avoid an NPE + if (level != null && !level.isClientSide) { + this.lifespan = SpongeGameConfigs.getForWorld(level).get().entity.item.despawnRate; + } + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/player/PlayerMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/player/PlayerMixin_Forge.java new file mode 100755 index 00000000000..e49f36b530a --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/player/PlayerMixin_Forge.java @@ -0,0 +1,41 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.world.entity.player; + +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.forge.mixin.core.world.entity.LivingEntityMixin_Forge; + +@Mixin(Player.class) +public class PlayerMixin_Forge extends LivingEntityMixin_Forge { + @Override + public boolean bridge$onLivingAttack( + final LivingEntity entity, final DamageSource source, final float amount + ) { + return true; + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/projectile/ThrownEnderpealMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/projectile/ThrownEnderpealMixin_Forge.java new file mode 100755 index 00000000000..ef47ed235d9 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/projectile/ThrownEnderpealMixin_Forge.java @@ -0,0 +1,44 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.world.entity.projectile; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.projectile.ThrownEnderpearl; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(ThrownEnderpearl.class) +public abstract class ThrownEnderpealMixin_Forge { + + @Redirect(method = "changeDimension", + at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/projectile/ThrownEnderpearl;getOwner()Lnet/minecraft/world/entity/Entity;")) + private Entity forge$preventUnsetOwnerUntilLater(final ThrownEnderpearl thrownEnderpearl) { + // This allows us to ensure the if statement after is always false + // We deal with this later (see the common mixin) + return null; + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/vehicle/BoatMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/vehicle/BoatMixin_Forge.java new file mode 100755 index 00000000000..f00eb8a1c45 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/vehicle/BoatMixin_Forge.java @@ -0,0 +1,53 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.world.entity.vehicle; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.vehicle.Boat; +import net.minecraft.world.level.LevelReader; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.common.bridge.world.entity.vehicle.BoatBridge; + +@Mixin(Boat.class) +public abstract class BoatMixin_Forge implements BoatBridge { + + @Redirect(method = "getGroundFriction", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/level/block/state/BlockState;getFriction(Lnet/minecraft/world/level/LevelReader;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/Entity;)F") + ) + private float forge$getBlockFrictionIfBoatIsNotOverridingMovingOnLand(BlockState caller, LevelReader level, BlockPos pos, Entity entity) { + final boolean movesOnLand = this.bridge$getMoveOnLand(); + final float friction = caller.getFriction(level, pos, entity); + if (movesOnLand && friction == 0.6f) { + return Blocks.ICE.getFriction(caller, level, pos, entity); + } + return friction; + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/FireBlockMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/FireBlockMixin_Forge.java new file mode 100755 index 00000000000..da13efce569 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/FireBlockMixin_Forge.java @@ -0,0 +1,74 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.world.level.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.FireBlock; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.common.bridge.server.level.ServerLevelBridge; +import org.spongepowered.common.event.ShouldFire; +import org.spongepowered.common.event.SpongeCommonEventFactory; + +@Mixin(FireBlock.class) +public class FireBlockMixin_Forge { + // forge changes the signature of this method + @Inject(method = "checkBurnOut", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z"), + require = 0, + expect = 0, + cancellable = true) + private void impl$onCatchFirePreCheck( + final Level world, final BlockPos pos, final int chance, final RandomSource random, final int age, final Direction dir, final CallbackInfo callbackInfo) { + if (!world.isClientSide) { + if (ShouldFire.CHANGE_BLOCK_EVENT_PRE && SpongeCommonEventFactory.callChangeBlockEventPre((ServerLevelBridge) world, pos).isCancelled()) { + callbackInfo.cancel(); + } + } + } + + @Inject(method = "checkBurnOut", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/level/Level;removeBlock(Lnet/minecraft/core/BlockPos;Z)Z"), + require = 0, + expect = 0, + cancellable = true) + private void impl$onCatchFirePreCheckOther( + final Level world, final BlockPos pos, final int chance, final RandomSource random, final int age, final Direction dir, final CallbackInfo callbackInfo) { + if (!world.isClientSide) { + if (ShouldFire.CHANGE_BLOCK_EVENT_PRE && SpongeCommonEventFactory.callChangeBlockEventPre((ServerLevelBridge) world, pos).isCancelled()) { + callbackInfo.cancel(); + } + } + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin_Forge.java new file mode 100755 index 00000000000..fa068009ebe --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin_Forge.java @@ -0,0 +1,183 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.core.world.level.block.entity; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.NonNullList; +import net.minecraft.core.RegistryAccess; +import net.minecraft.util.Mth; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.RecipeHolder; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.objectweb.asm.Opcodes; +import org.spongepowered.api.ResourceKey; +import org.spongepowered.api.block.entity.carrier.furnace.FurnaceBlockEntity; +import org.spongepowered.api.event.Cause; +import org.spongepowered.api.event.SpongeEventFactory; +import org.spongepowered.api.event.block.entity.CookingEvent; +import org.spongepowered.api.item.inventory.ItemStackSnapshot; +import org.spongepowered.api.item.inventory.transaction.SlotTransaction; +import org.spongepowered.api.item.recipe.cooking.CookingRecipe; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.Slice; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import org.spongepowered.common.MixinTargetHelper; +import org.spongepowered.common.SpongeCommon; +import org.spongepowered.common.bridge.block.entity.AbstractFurnaceBlockEntityBridge; +import org.spongepowered.common.event.tracking.PhaseTracker; +import org.spongepowered.common.inventory.adapter.impl.slots.SlotAdapter; +import org.spongepowered.common.item.util.ItemStackUtil; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +@Mixin(AbstractFurnaceBlockEntity.class) +public abstract class AbstractFurnaceBlockEntityMixin_Forge implements AbstractFurnaceBlockEntityBridge { + + // @formatter:off + @Shadow protected NonNullList items; + @Shadow int cookingProgress; + @Shadow private boolean shadow$canBurn(RegistryAccess registryAccess, @Nullable RecipeHolder recipe, NonNullList slots, int maxStackSize) { + throw new IllegalStateException("Mixin failed to shadow canBurn"); + } + // @formatter:on + + private boolean forgeImpl$filledWaterBucket; + + // Tick up and Start + @Redirect(method = "serverTick", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;canBurn(Lnet/minecraft/core/RegistryAccess;Lnet/minecraft/world/item/crafting/RecipeHolder;Lnet/minecraft/core/NonNullList;I)Z", + ordinal = 1)) + private static boolean forgeImpl$checkIfCanSmelt(final AbstractFurnaceBlockEntity entity, + final RegistryAccess registryAccess, + final RecipeHolder recipe, + final NonNullList slots, + final int maxStackSize) { + final var $this = (AbstractFurnaceBlockEntityMixin_Forge) (Object) (entity); + if (!$this.shadow$canBurn(registryAccess, recipe, slots, maxStackSize)) { + return false; + } + + final ItemStackSnapshot fuel = ItemStackUtil.snapshotOf(slots.get(1)); + + final Cause cause = PhaseTracker.getCauseStackManager().currentCause(); + if ($this.cookingProgress == 0) { // Start + final CookingEvent.Start event = SpongeEventFactory.createCookingEventStart(cause, (FurnaceBlockEntity) entity, Optional.of(fuel), + Optional.of((CookingRecipe) recipe.value()), Optional.of((ResourceKey) (Object) recipe.id())); + SpongeCommon.post(event); + return !event.isCancelled(); + } else { // Tick up + final ItemStackSnapshot cooking = ItemStackUtil.snapshotOf($this.items.get(0)); + final CookingEvent.Tick event = SpongeEventFactory.createCookingEventTick(cause, (FurnaceBlockEntity) entity, cooking, Optional.of(fuel), + Optional.of((CookingRecipe) recipe.value()), Optional.of((ResourceKey) (Object) recipe.id())); + SpongeCommon.post(event); + return !event.isCancelled(); + } + } + + // Tick down + @Redirect(method = "serverTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Mth;clamp(III)I")) + private static int forgeImpl$resetCookTimeIfCancelled(final int newCookTime, final int zero, final int totalCookTime, + final Level level, final BlockPos entityPos, final BlockState state, final AbstractFurnaceBlockEntity entity) { + final int clampedCookTime = Mth.clamp(newCookTime, zero, totalCookTime); + final var thisEntity = (AbstractFurnaceBlockEntityMixin_Forge) (Object) entity; + final ItemStackSnapshot fuel = ItemStackUtil.snapshotOf(thisEntity.items.get(1)); + final Cause cause = PhaseTracker.getCauseStackManager().currentCause(); + final var recipe = thisEntity.bridge$getCurrentRecipe(); + final ItemStackSnapshot cooking = ItemStackUtil.snapshotOf(thisEntity.items.get(0)); + final CookingEvent.Tick event = SpongeEventFactory.createCookingEventTick(cause, (FurnaceBlockEntity) entity, cooking, Optional.of(fuel), + recipe.map(r -> (CookingRecipe) r.value()), recipe.map(r -> (ResourceKey) (Object) r.id())); + SpongeCommon.post(event); + if (event.isCancelled()) { + return thisEntity.cookingProgress; // dont tick down + } + + return clampedCookTime; + } + + // Finish + @Inject(method = "burn", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/NonNullList;set(ILjava/lang/Object;)Ljava/lang/Object;"), + slice = @Slice( + from = @At(value = "FIELD", target = "Lnet/minecraft/world/level/block/Blocks;WET_SPONGE:Lnet/minecraft/world/level/block/Block;", opcode = Opcodes.GETSTATIC) + )) + private void forgeImpl$captureBucketFill(final RegistryAccess $$0, final RecipeHolder $$1, final NonNullList $$2, final int $$3, final CallbackInfoReturnable cir) { + final AbstractFurnaceBlockEntityMixin_Forge mixinSelf = MixinTargetHelper.cast(this); + mixinSelf.forgeImpl$filledWaterBucket = true; + } + + @Inject( + method = "burn", + locals = LocalCapture.CAPTURE_FAILHARD, + at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;shrink(I)V")) + private void forgeImpl$afterSmeltItem( + final RegistryAccess registryAccess, final RecipeHolder recipe, + final NonNullList slots, final int var2, + final CallbackInfoReturnable cir, + final ItemStack $$4, final ItemStack $$5, final ItemStack $$6 + ) { + final AbstractFurnaceBlockEntityMixin_Forge mixinSelf = MixinTargetHelper.cast(this); + final FurnaceBlockEntity entity = (FurnaceBlockEntity) this; + + final List transactions = new ArrayList<>(); + $$4.grow(1); + final ItemStackSnapshot originalSmeltItem = ItemStackUtil.snapshotOf($$4); + $$4.shrink(1); + transactions.add(new SlotTransaction(entity.inventory().slot(0).get(), originalSmeltItem, ItemStackUtil.snapshotOf($$4))); + + final boolean hasFuel = !mixinSelf.forgeImpl$filledWaterBucket; + if (mixinSelf.forgeImpl$filledWaterBucket) { + transactions.add(new SlotTransaction(entity.inventory().slot(1).get(), ItemStackSnapshot.empty(), ItemStackUtil.snapshotOf(slots.get(1)))); + } + mixinSelf.forgeImpl$filledWaterBucket = false; + + if ($$6.isEmpty()) { + transactions.add(new SlotTransaction(entity.inventory().slot(2).get(), ItemStackSnapshot.empty(), ItemStackUtil.snapshotOf($$5))); + } else if (ItemStack.isSameItemSameComponents($$6, $$5)) { + $$6.shrink(1); + final ItemStackSnapshot originalResult = ItemStackUtil.snapshotOf($$6); + $$6.grow(1); + transactions.add(new SlotTransaction(entity.inventory().slot(2).get(), originalResult, ItemStackUtil.snapshotOf($$6))); + } + final Optional fuel = hasFuel && !slots.get(1).isEmpty() ? Optional.of(ItemStackUtil.snapshotOf(slots.get(1))) : Optional.empty(); + final CookingEvent.Finish event = SpongeEventFactory.createCookingEventFinish(PhaseTracker.getCauseStackManager().currentCause(), entity, + fuel, Optional.ofNullable((CookingRecipe) recipe.value()), Optional.of((ResourceKey) (Object) recipe.id()), Collections.unmodifiableList(transactions)); + SpongeCommon.post(event); + + for (final SlotTransaction transaction : transactions) { + transaction.custom().ifPresent(item -> slots.set(((SlotAdapter) transaction.slot()).getOrdinal(), ItemStackUtil.fromSnapshotToNative(item))); + } + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/package-info.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/package-info.java new file mode 100755 index 00000000000..959126e7358 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/package-info.java @@ -0,0 +1,6 @@ + +@DefaultQualifier(NonNull.class) +package org.spongepowered.forge.mixin.core.world.level.block.entity; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/inventory/event/world/level/block/entity/HopperBlockEntityMixin_Inventory_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/inventory/event/world/level/block/entity/HopperBlockEntityMixin_Inventory_Forge.java new file mode 100755 index 00000000000..da26926ab18 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/inventory/event/world/level/block/entity/HopperBlockEntityMixin_Inventory_Forge.java @@ -0,0 +1,84 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.inventory.event.world.level.block.entity; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.Container; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.HopperBlockEntity; +import org.spongepowered.api.item.inventory.Inventory; +import org.spongepowered.api.item.inventory.transaction.SlotTransaction; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import org.spongepowered.common.accessor.world.level.block.entity.HopperBlockEntityAccessor; +import org.spongepowered.common.bridge.world.inventory.container.TrackedInventoryBridge; +import org.spongepowered.common.event.ShouldFire; +import org.spongepowered.common.event.inventory.InventoryEventFactory; +import org.spongepowered.common.inventory.util.InventoryUtil; + +@Mixin(HopperBlockEntity.class) +public abstract class HopperBlockEntityMixin_Inventory_Forge { + + @Redirect(method = "ejectItems", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/level/block/entity/HopperBlockEntity;isFullContainer(Lnet/minecraft/world/Container;Lnet/minecraft/core/Direction;)Z")) + private static boolean forge$throwTransferPreIfNotFull( + final Container attachedContainer, final Direction direction, final Level level, final BlockPos pos, final HopperBlockEntity block + ) { + final boolean result = HopperBlockEntityAccessor.invoker$isFullContainer(attachedContainer, direction); + if (result || !ShouldFire.TRANSFER_INVENTORY_EVENT_PRE) { + return result; + } + return InventoryEventFactory.callTransferPre(InventoryUtil.toInventory(block), InventoryUtil.toInventory(attachedContainer)).isCancelled(); + } + +// Post Captured Transactions + + @Inject(method = "ejectItems", locals = LocalCapture.CAPTURE_FAILHARD, + at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/item/ItemStack;isEmpty()Z", + ordinal = 1)) + private static void forge$afterPutStackInSlots( + final Level var0, final BlockPos var1, final HopperBlockEntity var3, + final CallbackInfoReturnable cir, final Container iInventory, final Direction enumFacing, + final int i, final ItemStack itemStack, final int count,final ItemStack itemStack1 + ) { + // after putStackInInventoryAllSlots if the transfer worked + if (ShouldFire.TRANSFER_INVENTORY_EVENT_POST && itemStack1.isEmpty()) { + // Capture Insert in Origin + final TrackedInventoryBridge capture = InventoryUtil.forCapture(var3); + final SlotTransaction sourceSlotTransaction = InventoryEventFactory.captureTransaction(capture, (Inventory) var3, i, itemStack); + // Call event + InventoryEventFactory.callTransferPost(capture, (Inventory) iInventory, InventoryUtil.toInventory(iInventory), itemStack, sourceSlotTransaction); + } + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/plugin/ForgeCorePlugin.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/plugin/ForgeCorePlugin.java new file mode 100755 index 00000000000..88d71961e72 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/plugin/ForgeCorePlugin.java @@ -0,0 +1,51 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.plugin; + +import cpw.mods.modlauncher.Environment; +import cpw.mods.modlauncher.Launcher; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.spongepowered.common.mixin.plugin.AbstractMixinConfigPlugin; + +import java.lang.reflect.InvocationTargetException; + +// just a way to get on the TCL nice and early +public class ForgeCorePlugin extends AbstractMixinConfigPlugin { + + private static final Logger LOGGER = LogManager.getLogger(); + + public ForgeCorePlugin() { + // todo: too tired for gradle + try { + Class.forName("org.spongepowered.forge.applaunch.plugin.ForgePluginPlatform") + .getMethod("bootstrap", Environment.class) + .invoke(null, Launcher.INSTANCE.environment()); + } catch (final ClassNotFoundException | InvocationTargetException | IllegalAccessException | NoSuchMethodException ex) { + ForgeCorePlugin.LOGGER.error("Failed to bootstrap the Forge plugin platform on TCL", ex); + } + } + +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/server/level/ServerPlayerGameModeMixin_Forge_Tracker.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/server/level/ServerPlayerGameModeMixin_Forge_Tracker.java new file mode 100755 index 00000000000..b3f8c60f891 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/server/level/ServerPlayerGameModeMixin_Forge_Tracker.java @@ -0,0 +1,82 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.tracker.server.level; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.level.ServerPlayerGameMode; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.common.event.tracking.PhaseContext; +import org.spongepowered.common.event.tracking.PhaseTracker; +import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor; +import org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect; +import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier; +import org.spongepowered.common.event.tracking.context.transaction.effect.InventoryEffect; +import org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction; + +@Mixin(ServerPlayerGameMode.class) +public abstract class ServerPlayerGameModeMixin_Forge_Tracker { + + // @formatter:off + @Shadow @Final protected ServerPlayer player; + // @formatter:on + + @Redirect( + method = "destroyBlock", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/item/ItemStack;mineBlock(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/player/Player;)V" + ) + ) + private void forgeTracker$pushTransactionAndEffect( + final ItemStack itemStack, final Level level, final BlockState state, final BlockPos pos, + final Player player + ) { + final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext(); + final TransactionalCaptureSupplier transactor = context.getTransactor(); + // Log the prepare drops here because Forge rewrites + // this method to call mine block before calling destroy block + // and mods will possibly already have performed modifications on + // the block before we can capture it in level.destroy. + transactor.logBlockDrops(level, pos, state, level.getBlockEntity(pos)); + + itemStack.mineBlock(level, state, pos, player); + // Needs to get logged as a sideeffect under the BlockChange + try (EffectTransactor ignored = context.getTransactor().pushEffect(new ResultingTransactionBySideEffect( + InventoryEffect.getInstance()))) { + transactor.logPlayerInventoryChange(this.player, PlayerInventoryTransaction.EventCreator.STANDARD); + this.player.inventoryMenu.broadcastChanges(); + } + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/BlockMixin_Forge_Tracker.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/BlockMixin_Forge_Tracker.java new file mode 100755 index 00000000000..64005dd321a --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/BlockMixin_Forge_Tracker.java @@ -0,0 +1,51 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.tracker.world.level.block; + + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.common.bridge.RegistryBackedTrackableBridge; +import org.spongepowered.forge.mixin.tracker.world.level.block.state.BlockBehaviorMixin_Forge_Tracker; + +@Mixin(Block.class) +public abstract class BlockMixin_Forge_Tracker extends BlockBehaviorMixin_Forge_Tracker implements RegistryBackedTrackableBridge { + + //@formatter:off + @Shadow public abstract BlockState defaultBlockState(); + //@formatter:on + + @Override + protected void forgeTracker$initializeTrackingState(CallbackInfoReturnable cir) { + // TODO Not the best check but the tracker options only matter during block ticks... + if (this.isRandomlyTicking(this.defaultBlockState())) { + this.bridge$refreshTrackerStates(); + } + } +} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/state/BlockBehaviorMixin_Forge_Tracker.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/state/BlockBehaviorMixin_Forge_Tracker.java new file mode 100755 index 00000000000..8784263a379 --- /dev/null +++ b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/state/BlockBehaviorMixin_Forge_Tracker.java @@ -0,0 +1,51 @@ +/* + * This file is part of Sponge, licensed under the MIT License (MIT). + * + * Copyright (c) SpongePowered + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.spongepowered.forge.mixin.tracker.world.level.block.state; + + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(BlockBehaviour.class) +public abstract class BlockBehaviorMixin_Forge_Tracker { + @Shadow protected abstract boolean isRandomlyTicking(BlockState $$0); + + @Inject( + method = "getLootTable", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/level/block/state/BlockBehaviour;lootTableSupplier:Ljava/util/function/Supplier;", + remap = false + ) + ) + protected void forgeTracker$initializeTrackingState(CallbackInfoReturnable cir) { + } +} diff --git a/neoforge/src/mixins/resources/mixins.spongeforge.api.json b/neoforge/src/mixins/resources/mixins.spongeforge.api.json new file mode 100755 index 00000000000..afbe11ab0d7 --- /dev/null +++ b/neoforge/src/mixins/resources/mixins.spongeforge.api.json @@ -0,0 +1,14 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "org.spongepowered.forge.mixin.api", + "target": "@env(DEFAULT)", + "compatibilityLevel": "JAVA_8", + "priority": 1300, + "mixins": [ + "minecraft.server.MinecraftServerMixin_Forge_API" + ], + "overwrites": { + "conformVisibility": true + } +} diff --git a/neoforge/src/mixins/resources/mixins.spongeforge.core.json b/neoforge/src/mixins/resources/mixins.spongeforge.core.json new file mode 100755 index 00000000000..2a80060ac44 --- /dev/null +++ b/neoforge/src/mixins/resources/mixins.spongeforge.core.json @@ -0,0 +1,46 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "org.spongepowered.forge.mixin.core", + "plugin": "org.spongepowered.forge.mixin.plugin.ForgeCorePlugin", + "target": "@env(DEFAULT)", + "compatibilityLevel": "JAVA_8", + "priority": 1301, + "mixins": [ + "api.event.EventMixin_Forge", + "api.event.block.ChangeBlockEvent_AllMixin_Forge", + "api.event.entity.ChangeEntityWorldEvent_PreMixin_Forge", + "api.event.entity.ChangeEventWorldEvent_PostMixin_Forge", + "commands.CommandsMixin_Forge", + "minecraftforge.MinecraftForgeMixin_Forge", + "minecraftforge.event.entity.EntityTravelToDimensionEventMixin_Forge", + "minecraftforge.event.entity.player.PlayerEvent_PlayerChangedDimensionEventMixin_Forge", + "minecraftforge.event.world.BlockEvent_BreakEventMixin_Forge", + "minecraftforge.event.world.BlockEventMixin_Forge", + "minecraftforge.internal.BrandingControlMixin_Forge", + "minecraftforge.registries.ForgeRegistryMixin_Forge", + "minecraftforge.registries.RegistryManagerMixin_Forge", + "network.ConnectionMixin_Forge", + "server.BootstrapMixin_Forge", + "server.MinecraftServerMixin_Forge", + "server.commands.SpreadPlayersCommandMixin_Forge", + "server.level.ServerPlayerMixin_Forge", + "server.network.ServerGamePacketListenerImplMixin_Forge", + "server.network.ServerLoginPacketListenerImplMixin_Forge", + "world.entity.LivingEntityMixin_Forge", + "world.entity.LivingEntityMixin_Forge_Attack_Impl", + "world.entity.item.ItemEntityMixin_Forge", + "world.entity.player.PlayerMixin_Forge", + "world.entity.projectile.ThrownEnderpealMixin_Forge", + "world.entity.vehicle.BoatMixin_Forge", + "world.level.block.FireBlockMixin_Forge", + "world.level.block.entity.AbstractFurnaceBlockEntityMixin_Forge" + ], + "client": [ + "client.MinecraftMixin_Forge", + "client.main.MainMixin_Forge" + ], + "server": [ + "server.MainMixin_Forge" + ] +} diff --git a/neoforge/src/mixins/resources/mixins.spongeforge.inventory.json b/neoforge/src/mixins/resources/mixins.spongeforge.inventory.json new file mode 100755 index 00000000000..ac8b6037eac --- /dev/null +++ b/neoforge/src/mixins/resources/mixins.spongeforge.inventory.json @@ -0,0 +1,11 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "org.spongepowered.forge.mixin.inventory", + "plugin": "org.spongepowered.forge.mixin.plugin.ForgeCorePlugin", + "target": "@env(DEFAULT)", + "priority": 1300, + "mixins": [ + "event.world.level.block.entity.HopperBlockEntityMixin_Inventory_Forge" + ] +} diff --git a/neoforge/src/mixins/resources/mixins.spongeforge.tracker.json b/neoforge/src/mixins/resources/mixins.spongeforge.tracker.json new file mode 100755 index 00000000000..3061f2ca8ce --- /dev/null +++ b/neoforge/src/mixins/resources/mixins.spongeforge.tracker.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "org.spongepowered.forge.mixin.tracker", + "target": "@env(DEFAULT)", + "compatibilityLevel": "JAVA_8", + "priority": 1302, + "mixins": [ + "server.level.ServerPlayerGameModeMixin_Forge_Tracker", + "world.level.block.BlockMixin_Forge_Tracker", + "world.level.block.state.BlockBehaviorMixin_Forge_Tracker" + ] +} diff --git a/settings.gradle.kts b/settings.gradle.kts old mode 100644 new mode 100755 index 6ad57d49c5e..a1c0d1e5333 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -93,6 +93,22 @@ if (spongeForgeEnabledInCi.toBoolean()) { include(":SpongeForge") project(":SpongeForge").projectDir = file("forge") } +val spongeNeoForge = file("spongeneoforge.settings.gradle.kts") +if (spongeNeoForge.exists()) { + apply(from = spongeNeoForge) +} else { + spongeNeoForge.writeText(listOf( + "// Uncomment to enable SpongeForge module.", + "// By default only Sponge and SpongeVanilla are made available", + "//include(\":SpongeNeoForge\")", + "//project(\":SpongeNeoForge\").projectDir = file(\"neoforge\")" + ).joinToString(separator = System.lineSeparator(), postfix = System.lineSeparator())) +} +val spongeNeoForgeEnabledInCi: String = startParameter.projectProperties.getOrDefault("enableSpongeNeoForge", "true") +if (spongeForgeEnabledInCi.toBoolean()) { + include(":SpongeNeoForge") + project(":SpongeNeoForge").projectDir = file("neoforge") +} // Include properties from API project (with api prefix) val apiProps = file("SpongeAPI/gradle.properties") From 0c11f60ee4e52d08249e96bf02cbf15bbb2b5eaf Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Wed, 21 Aug 2024 03:38:29 +0700 Subject: [PATCH 02/13] Create spongeneoforge.settings.gradle.kts --- spongeneoforge.settings.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 spongeneoforge.settings.gradle.kts diff --git a/spongeneoforge.settings.gradle.kts b/spongeneoforge.settings.gradle.kts new file mode 100644 index 00000000000..28d34f5baeb --- /dev/null +++ b/spongeneoforge.settings.gradle.kts @@ -0,0 +1,4 @@ +// Uncomment to enable SpongeForge module. +// By default only Sponge and SpongeVanilla are made available +//include(":SpongeNeoForge") +//project(":SpongeNeoForge").projectDir = file("neoforge") From 2625c3155a6d5cc869738e1e970b3bb4d726f33f Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Wed, 21 Aug 2024 04:33:41 +0700 Subject: [PATCH 03/13] Drop neoforge folder --- neoforge/build.gradle.kts | 541 ------------------ neoforge/gradle.properties | 8 - .../mixins.spongeforge.accessors.json | 7 - .../PluginDependencyConfigurable.java | 77 --- .../metadata/PluginFileConfigurable.java | 140 ----- .../metadata/PluginMetadataConfigurable.java | 65 --- .../loading/metadata/PluginMetadataUtils.java | 83 --- .../loading/moddiscovery/ModFileParsers.java | 112 ---- .../SpongeForgeDependencyLocator.java | 82 --- .../moddiscovery/SpongeForgeModLocator.java | 93 --- .../moddiscovery/library/AsyncUtils.java | 52 -- .../moddiscovery/library/InstallerUtils.java | 169 ------ .../moddiscovery/library/LibraryManager.java | 246 -------- .../library/model/sponge/Libraries.java | 57 -- .../model/sponge/SonatypeResponse.java | 46 -- .../locator/EnvironmentPluginLocator.java | 97 ---- .../locator/PluginsDirectoryLocator.java | 94 --- .../applaunch/plugin/ForgePluginPlatform.java | 134 ----- .../transformation/ListenerTransformer.java | 100 ---- .../SpongeForgeTransformationService.java | 155 ----- ...ods.modlauncher.api.ITransformationService | 1 - ...forge.forgespi.locating.IDependencyLocator | 1 - ...necraftforge.forgespi.locating.IModLocator | 3 - .../provider/JavaPluginLanguageProvider.java | 134 ----- ...rge.forgespi.language.IModLanguageProvider | 1 - .../forge/launch/ForgeLaunch.java | 106 ---- .../forge/launch/ForgeMappingManager.java | 61 -- .../forge/launch/ForgePlatform.java | 50 -- .../bridge/event/ForgeEventBridge_Forge.java | 61 -- .../bridge/event/SpongeEventBridge_Forge.java | 59 -- .../launch/command/ForgeCommandManager.java | 108 ---- .../forge/launch/event/ForgeEventManager.java | 168 ------ .../forge/launch/event/ListenerLookups.java | 43 -- .../forge/launch/event/SpongeEventBus.java | 103 ---- .../launch/inject/SpongeForgeModule.java | 47 -- .../launch/plugin/ForgePluginContainer.java | 101 ---- .../launch/plugin/ForgePluginManager.java | 62 -- .../launch/plugin/PluginModContainer.java | 129 ----- .../org/spongepowered/forge/ForgeClient.java | 31 - .../org/spongepowered/forge/ForgeEngine.java | 30 - .../org/spongepowered/forge/ForgeServer.java | 34 -- .../org/spongepowered/forge/SpongeAPIMod.java | 31 - .../spongepowered/forge/SpongeForgeMod.java | 151 ----- .../org/spongepowered/forge/SpongeMod.java | 31 - .../forge/hook/ForgeChannelHooks.java | 59 -- .../forge/hook/ForgeEventHooks.java | 54 -- .../forge/hook/ForgeGeneralHooks.java | 39 -- .../forge/hook/ForgeItemHooks.java | 31 - .../forge/hook/ForgeWorldHooks.java | 66 --- .../forge/world/server/ForgeWorldManager.java | 35 -- .../resource-templates/META-INF/mods.toml | 56 -- .../src/main/resources/forge.superclasschange | 3 - neoforge/src/main/resources/pack.mcmeta | 6 - .../MinecraftServerMixin_Forge_API.java | 49 -- .../core/api/event/EventMixin_Forge.java | 34 -- .../ChangeBlockEvent_AllMixin_Forge.java | 66 --- ...ChangeEntityWorldEvent_PreMixin_Forge.java | 49 -- ...ChangeEventWorldEvent_PostMixin_Forge.java | 53 -- .../core/client/MinecraftMixin_Forge.java | 40 -- .../core/client/main/MainMixin_Forge.java | 50 -- .../core/commands/CommandsMixin_Forge.java | 101 ---- .../MinecraftForgeMixin_Forge.java | 46 -- ...tityTravelToDimensionEventMixin_Forge.java | 76 --- ...layerChangedDimensionEventMixin_Forge.java | 72 --- .../event/world/BlockEventMixin_Forge.java | 43 -- .../BlockEvent_BreakEventMixin_Forge.java | 99 ---- .../internal/BrandingControlMixin_Forge.java | 51 -- .../registries/ForgeRegistryMixin_Forge.java | 88 --- .../RegistryManagerMixin_Forge.java | 51 -- .../core/network/ConnectionMixin_Forge.java | 46 -- .../core/server/BootstrapMixin_Forge.java | 62 -- .../mixin/core/server/MainMixin_Forge.java | 46 -- .../server/MinecraftServerMixin_Forge.java | 53 -- .../SpreadPlayersCommandMixin_Forge.java | 53 -- .../server/level/ServerPlayerMixin_Forge.java | 51 -- ...rverGamePacketListenerImplMixin_Forge.java | 66 --- ...verLoginPacketListenerImplMixin_Forge.java | 50 -- .../world/entity/LivingEntityMixin_Forge.java | 64 --- .../LivingEntityMixin_Forge_Attack_Impl.java | 46 -- .../entity/item/ItemEntityMixin_Forge.java | 53 -- .../entity/player/PlayerMixin_Forge.java | 41 -- .../ThrownEnderpealMixin_Forge.java | 44 -- .../world/entity/vehicle/BoatMixin_Forge.java | 53 -- .../level/block/FireBlockMixin_Forge.java | 74 --- ...AbstractFurnaceBlockEntityMixin_Forge.java | 183 ------ .../level/block/entity/package-info.java | 6 - ...opperBlockEntityMixin_Inventory_Forge.java | 84 --- .../forge/mixin/plugin/ForgeCorePlugin.java | 51 -- ...rverPlayerGameModeMixin_Forge_Tracker.java | 82 --- .../level/block/BlockMixin_Forge_Tracker.java | 51 -- .../BlockBehaviorMixin_Forge_Tracker.java | 51 -- .../resources/mixins.spongeforge.api.json | 14 - .../resources/mixins.spongeforge.core.json | 46 -- .../mixins.spongeforge.inventory.json | 11 - .../resources/mixins.spongeforge.tracker.json | 13 - 95 files changed, 6615 deletions(-) delete mode 100755 neoforge/build.gradle.kts delete mode 100755 neoforge/gradle.properties delete mode 100755 neoforge/src/accessors/resources/mixins.spongeforge.accessors.json delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginDependencyConfigurable.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginFileConfigurable.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataConfigurable.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataUtils.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/ModFileParsers.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeDependencyLocator.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeModLocator.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/AsyncUtils.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/InstallerUtils.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/LibraryManager.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/Libraries.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/SonatypeResponse.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/EnvironmentPluginLocator.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/PluginsDirectoryLocator.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/plugin/ForgePluginPlatform.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/ListenerTransformer.java delete mode 100755 neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/SpongeForgeTransformationService.java delete mode 100755 neoforge/src/applaunch/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService delete mode 100755 neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IDependencyLocator delete mode 100755 neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator delete mode 100755 neoforge/src/lang/java/org/spongepowered/forge/lang/provider/JavaPluginLanguageProvider.java delete mode 100755 neoforge/src/lang/resources/META-INF/services/net.minecraftforge.forgespi.language.IModLanguageProvider delete mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeLaunch.java delete mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeMappingManager.java delete mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/ForgePlatform.java delete mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/ForgeEventBridge_Forge.java delete mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/SpongeEventBridge_Forge.java delete mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/command/ForgeCommandManager.java delete mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/event/ForgeEventManager.java delete mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/event/ListenerLookups.java delete mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/event/SpongeEventBus.java delete mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/inject/SpongeForgeModule.java delete mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginContainer.java delete mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginManager.java delete mode 100755 neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/PluginModContainer.java delete mode 100755 neoforge/src/main/java/org/spongepowered/forge/ForgeClient.java delete mode 100755 neoforge/src/main/java/org/spongepowered/forge/ForgeEngine.java delete mode 100755 neoforge/src/main/java/org/spongepowered/forge/ForgeServer.java delete mode 100755 neoforge/src/main/java/org/spongepowered/forge/SpongeAPIMod.java delete mode 100755 neoforge/src/main/java/org/spongepowered/forge/SpongeForgeMod.java delete mode 100755 neoforge/src/main/java/org/spongepowered/forge/SpongeMod.java delete mode 100755 neoforge/src/main/java/org/spongepowered/forge/hook/ForgeChannelHooks.java delete mode 100755 neoforge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java delete mode 100755 neoforge/src/main/java/org/spongepowered/forge/hook/ForgeGeneralHooks.java delete mode 100755 neoforge/src/main/java/org/spongepowered/forge/hook/ForgeItemHooks.java delete mode 100755 neoforge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java delete mode 100755 neoforge/src/main/java/org/spongepowered/forge/world/server/ForgeWorldManager.java delete mode 100755 neoforge/src/main/resource-templates/META-INF/mods.toml delete mode 100755 neoforge/src/main/resources/forge.superclasschange delete mode 100755 neoforge/src/main/resources/pack.mcmeta delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/api/minecraft/server/MinecraftServerMixin_Forge_API.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/EventMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/block/ChangeBlockEvent_AllMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEntityWorldEvent_PreMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEventWorldEvent_PostMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/MinecraftMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/main/MainMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/commands/CommandsMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/MinecraftForgeMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/EntityTravelToDimensionEventMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/player/PlayerEvent_PlayerChangedDimensionEventMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEventMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEvent_BreakEventMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/internal/BrandingControlMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/ForgeRegistryMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/RegistryManagerMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/network/ConnectionMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/BootstrapMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MainMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MinecraftServerMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/commands/SpreadPlayersCommandMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/level/ServerPlayerMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerGamePacketListenerImplMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerLoginPacketListenerImplMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge_Attack_Impl.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/item/ItemEntityMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/player/PlayerMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/projectile/ThrownEnderpealMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/vehicle/BoatMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/FireBlockMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/package-info.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/inventory/event/world/level/block/entity/HopperBlockEntityMixin_Inventory_Forge.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/plugin/ForgeCorePlugin.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/server/level/ServerPlayerGameModeMixin_Forge_Tracker.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/BlockMixin_Forge_Tracker.java delete mode 100755 neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/state/BlockBehaviorMixin_Forge_Tracker.java delete mode 100755 neoforge/src/mixins/resources/mixins.spongeforge.api.json delete mode 100755 neoforge/src/mixins/resources/mixins.spongeforge.core.json delete mode 100755 neoforge/src/mixins/resources/mixins.spongeforge.inventory.json delete mode 100755 neoforge/src/mixins/resources/mixins.spongeforge.tracker.json diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts deleted file mode 100755 index 571443d18de..00000000000 --- a/neoforge/build.gradle.kts +++ /dev/null @@ -1,541 +0,0 @@ -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -import net.fabricmc.loom.api.LoomGradleExtensionAPI - -buildscript { - repositories { - maven("https://repo.spongepowered.org/repository/maven-public") { - name = "sponge" - } - maven("https://maven.neoforged.net/releases/") { - name = "neoforge" - } - maven("https://maven.architectury.dev/") - } -} - -plugins { - alias(libs.plugins.shadow) - id("implementation-structure") - alias(libs.plugins.blossom) - id("dev.architectury.loom") version "1.6-SNAPSHOT" -} - -val commonProject = parent!! -val transformersProject = parent!!.project(":modlauncher-transformers") -val apiVersion: String by project -val minecraftVersion: String by project -val neoForgeVersion: String by project -val recommendedVersion: String by project -val organization: String by project -val projectUrl: String by project - -val testPluginsProject: Project? = rootProject.subprojects.find { "testplugins" == it.name } - -description = "The SpongeAPI implementation for MinecraftForge" -version = spongeImpl.generatePlatformBuildVersionString(apiVersion, minecraftVersion, recommendedVersion, neoForgeVersion) - -repositories { - maven("https://repo.spongepowered.org/repository/maven-public/") { - name = "sponge" - } - maven("https://maven.neoforged.net/releases/") { - name = "neoforge" - } -} - -// SpongeForge libraries -val serviceLibrariesConfig: NamedDomainObjectProvider = configurations.register("spongeServiceLibraries") -val gameLibrariesConfig: NamedDomainObjectProvider = configurations.register("spongeGameLibraries") - -val gameManagedLibrariesConfig: NamedDomainObjectProvider = configurations.register("spongeGameManagedLibraries") - -val serviceShadedLibrariesConfig: NamedDomainObjectProvider = configurations.register("spongeServiceShadedLibraries") -val gameShadedLibrariesConfig: NamedDomainObjectProvider = configurations.register("spongeGameShadedLibraries") - -val runTaskOnlyConfig: NamedDomainObjectProvider = configurations.register("runTaskOnly") - -configurations.named("forgeRuntimeLibrary") { - extendsFrom(serviceLibrariesConfig.get()) -} - -// ModLauncher layers -val serviceLayerConfig: NamedDomainObjectProvider = configurations.register("serviceLayer") { - extendsFrom(serviceLibrariesConfig.get()) - extendsFrom(configurations.getByName("forgeDependencies")) -} -val langLayerConfig: NamedDomainObjectProvider = configurations.register("langLayer") { - extendsFrom(configurations.getByName("forgeDependencies")) -} -val gameLayerConfig: NamedDomainObjectProvider = configurations.register("gameLayer") { - extendsFrom(serviceLayerConfig.get()) - extendsFrom(langLayerConfig.get()) - extendsFrom(gameLibrariesConfig.get()) - - afterEvaluate { - extendsFrom(configurations.getByName("minecraftNamedCompile")) - } -} - -// Common source sets and configurations -val launchConfig: NamedDomainObjectProvider = commonProject.configurations.named("launch") -val accessors: NamedDomainObjectProvider = commonProject.sourceSets.named("accessors") -val launch: NamedDomainObjectProvider = commonProject.sourceSets.named("launch") -val applaunch: NamedDomainObjectProvider = commonProject.sourceSets.named("applaunch") -val mixins: NamedDomainObjectProvider = commonProject.sourceSets.named("mixins") -val main: NamedDomainObjectProvider = commonProject.sourceSets.named("main") - -// Forge source sets -val forgeMain by sourceSets.named("main") { - // implementation (compile) dependencies - spongeImpl.applyNamedDependencyOnOutput(commonProject, accessors.get(), this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(commonProject, launch.get(), this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(commonProject, applaunch.get(), this, project, this.implementationConfigurationName) - - configurations.named(implementationConfigurationName) { - extendsFrom(gameLayerConfig.get()) - } -} -val forgeLaunch by sourceSets.register("launch") { - // implementation (compile) dependencies - spongeImpl.applyNamedDependencyOnOutput(commonProject, launch.get(), this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(commonProject, applaunch.get(), this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(commonProject, main.get(), this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(project, this, forgeMain, project, forgeMain.implementationConfigurationName) - - configurations.named(implementationConfigurationName) { - extendsFrom(gameLayerConfig.get()) - } -} -val forgeAccessors by sourceSets.register("accessors") { - spongeImpl.applyNamedDependencyOnOutput(commonProject, mixins.get(), this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(project, this, forgeLaunch, project, forgeLaunch.implementationConfigurationName) - - configurations.named(implementationConfigurationName) { - extendsFrom(gameLayerConfig.get()) - } -} -val forgeMixins by sourceSets.register("mixins") { - // implementation (compile) dependencies - spongeImpl.applyNamedDependencyOnOutput(commonProject, mixins.get(), this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(commonProject, accessors.get(), this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(commonProject, launch.get(), this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(commonProject, applaunch.get(), this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(commonProject, main.get(), this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(project, forgeMain, this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(project, forgeAccessors, this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(project, forgeLaunch, this, project, this.implementationConfigurationName) - - configurations.named(implementationConfigurationName) { - extendsFrom(gameLayerConfig.get()) - } -} -val forgeLang by sourceSets.register("lang") { - configurations.named(implementationConfigurationName) { - extendsFrom(langLayerConfig.get()) - } -} -val forgeAppLaunch by sourceSets.register("applaunch") { - // implementation (compile) dependencies - spongeImpl.applyNamedDependencyOnOutput(commonProject, applaunch.get(), this, project, this.implementationConfigurationName) - spongeImpl.applyNamedDependencyOnOutput(project, this, forgeLaunch, project, forgeLaunch.implementationConfigurationName) - - configurations.named(implementationConfigurationName) { - extendsFrom(serviceLayerConfig.get()) - } -} - -configurations.configureEach { - exclude(group = "net.minecraft", module = "joined") - if (name != "minecraft") { // awful terrible hack sssh - exclude(group = "com.mojang", module = "minecraft") - } - - // Fix that can be found in Forge MDK too - resolutionStrategy { - force("net.sf.jopt-simple:jopt-simple:5.0.4") - } -} - -extensions.configure(LoomGradleExtensionAPI::class) { - silentMojangMappingsLicense() - accessWidenerPath.set(file("../src/main/resources/common.accesswidener")) - - mixin { - useLegacyMixinAp.set(false) - } - - neoForge { - - } - - mods { - named("main") { - sourceSet(forgeMixins) - sourceSet(forgeAccessors) - sourceSet(forgeLaunch) - - sourceSet(main.get(), commonProject) - sourceSet(mixins.get(), commonProject) - sourceSet(accessors.get(), commonProject) - sourceSet(launch.get(), commonProject) - - configuration(gameManagedLibrariesConfig.get()) - configuration(gameShadedLibrariesConfig.get()) - } - } - - // Arch-loom bug, skip broken union-relauncher - runs.forEach { - it.mainClass.set("net.minecraftforge.bootstrap.ForgeBootstrap") - } -} - -dependencies { - "minecraft"("com.mojang:minecraft:${minecraftVersion}") - "neoForge"("net.neoforged:neoforge:$neoForgeVersion") - "mappings"(loom.layered { - officialMojangMappings { - nameSyntheticMembers = true - } - }) - - api(project(":", configuration = "launch")) { - exclude(group = "org.spongepowered", module = "mixin") - } - implementation(project(":", configuration = "accessors")) { - exclude(group = "org.spongepowered", module = "mixin") - } - implementation(project(commonProject.path)) { - exclude(group = "org.spongepowered", module = "mixin") - } - - forgeMixins.implementationConfigurationName(project(commonProject.path)) - - val serviceLibraries = serviceLibrariesConfig.name - serviceLibraries(apiLibs.pluginSpi) - serviceLibraries(project(transformersProject.path)) - serviceLibraries(platform(apiLibs.configurate.bom)) - serviceLibraries(apiLibs.configurate.core) { - exclude(group = "org.checkerframework", module = "checker-qual") - } - serviceLibraries(apiLibs.configurate.hocon) { - exclude(group = "org.spongepowered", module = "configurate-core") - exclude(group = "org.checkerframework", module = "checker-qual") - } - serviceLibraries(libs.configurate.jackson) { - exclude(group = "org.spongepowered", module = "configurate-core") - exclude(group = "org.checkerframework", module = "checker-qual") - } - - val gameLibraries = gameLibrariesConfig.name - gameLibraries("org.spongepowered:spongeapi:$apiVersion") - gameLibraries(libs.javaxInject) - gameLibraries(platform(apiLibs.adventure.bom)) - gameLibraries(libs.adventure.serializerConfigurate4) - - val serviceShadedLibraries = serviceShadedLibrariesConfig.name - serviceShadedLibraries(project(transformersProject.path)) { isTransitive = false } - - val gameShadedLibraries = gameShadedLibrariesConfig.name - gameShadedLibraries("org.spongepowered:spongeapi:$apiVersion") { isTransitive = false } - - afterEvaluate { - spongeImpl.copyModulesExcludingProvided(serviceLibrariesConfig.get(), configurations.getByName("forgeDependencies"), serviceShadedLibrariesConfig.get()) - spongeImpl.copyModulesExcludingProvided(gameLibrariesConfig.get(), serviceLayerConfig.get(), gameManagedLibrariesConfig.get()) - } - - val runTaskOnly = runTaskOnlyConfig.name - // Arch-loom bug, fix support of MOD_CLASSES - runTaskOnly("net.minecraftforge:bootstrap-dev:2.1.3") -} - -val forgeManifest = java.manifest { - attributes( - "Specification-Title" to "SpongeForge", - "Specification-Vendor" to "SpongePowered", - "Specification-Version" to apiVersion, - "Implementation-Title" to project.name, - "Implementation-Version" to spongeImpl.generatePlatformBuildVersionString(apiVersion, minecraftVersion, recommendedVersion, neoForgeVersion), - "Implementation-Vendor" to "SpongePowered" - ) - // These two are included by most CI's - System.getenv()["GIT_COMMIT"]?.apply { attributes("Git-Commit" to this) } - System.getenv()["GIT_BRANCH"]?.apply { attributes("Git-Branch" to this) } -} - -val mixinConfigs: MutableSet = spongeImpl.mixinConfigurations - -tasks { - jar { - manifest.from(forgeManifest) - } - val forgeAppLaunchJar by registering(Jar::class) { - archiveClassifier.set("applaunch") - manifest.from(forgeManifest) - from(forgeAppLaunch.output) - } - val forgeLaunchJar by registering(Jar::class) { - archiveClassifier.set("launch") - manifest.from(forgeManifest) - from(forgeLaunch.output) - } - val forgeAccessorsJar by registering(Jar::class) { - archiveClassifier.set("accessors") - manifest.from(forgeManifest) - from(forgeAccessors.output) - } - val forgeMixinsJar by registering(Jar::class) { - archiveClassifier.set("mixins") - manifest.from(forgeManifest) - from(forgeMixins.output) - } - val forgeLangJar by registering(Jar::class) { - archiveClassifier.set("lang") - manifest { - from(forgeManifest) - attributes("FMLModType" to "LANGPROVIDER") - } - from(forgeLang.output) - } - - val forgeServicesDevJar by registering(Jar::class) { - archiveClassifier.set("services") - manifest.from(forgeManifest) - - from(commonProject.sourceSets.named("applaunch").map { it.output }) - from(forgeAppLaunch.output) - - duplicatesStrategy = DuplicatesStrategy.WARN - } - - afterEvaluate { - withType(net.fabricmc.loom.task.AbstractRunTask::class) { - // Default classpath is a mess, we better start a new one from scratch - classpath = files( - configurations.getByName("forgeRuntimeLibrary"), - forgeServicesDevJar, forgeLangJar, runTaskOnlyConfig - ) - - testPluginsProject?.also { - val testPluginsOutput = it.sourceSets.getByName("main").output - val dirs: MutableList = mutableListOf() - dirs.add(testPluginsOutput.resourcesDir!!) - dirs.addAll(testPluginsOutput.classesDirs) - environment["SPONGE_PLUGINS"] = dirs.joinToString("&") - - dependsOn(it.tasks.classes) - } - - argumentProviders += CommandLineArgumentProvider { - mixinConfigs.asSequence() - .flatMap { sequenceOf("--mixin.config", it) } - .toList() - } - - // jvmArguments.add("-Dbsl.debug=true") // Uncomment to debug bootstrap classpath - - sourceSets.forEach { - dependsOn(it.classesTaskName) - } - } - } - - val installerResources = project.layout.buildDirectory.dir("generated/resources/installer") - forgeAppLaunch.resources.srcDir(installerResources) - - val emitDependencies by registering(org.spongepowered.gradle.impl.OutputDependenciesToJson::class) { - group = "sponge" - this.dependencies("main", gameManagedLibrariesConfig) - this.excludedDependencies(gameShadedLibrariesConfig) - - outputFile.set(installerResources.map { it.file("org/spongepowered/forge/applaunch/loading/moddiscovery/libraries.json") }) - } - named(forgeAppLaunch.processResourcesTaskName).configure { - dependsOn(emitDependencies) - } - - val forgeServicesShadowJar by register("servicesShadowJar", ShadowJar::class) { - group = "shadow" - archiveClassifier.set("services") - - mergeServiceFiles() - configurations = listOf(serviceShadedLibrariesConfig.get()) - exclude("META-INF/INDEX.LIST", "META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA", "module-info.class") - - manifest { - attributes("Automatic-Module-Name" to "spongeforge.services") - attributes("Multi-Release" to true) - from(forgeManifest) - } - - from(commonProject.sourceSets.named("applaunch").map { it.output }) - from(forgeAppLaunch.output) - - // Make sure to relocate access widener so that we don't conflict with other coremods - relocate("net.fabricmc.accesswidener", "org.spongepowered.forge.libs.accesswidener") - } - - shadowJar { - group = "shadow" - archiveClassifier.set("mod") - - mergeServiceFiles() - configurations = listOf(gameShadedLibrariesConfig.get()) - - manifest { - attributes( - "Access-Widener" to "common.accesswidener", - "Superclass-Transformer" to "common.superclasschange,forge.superclasschange", - "MixinConfigs" to mixinConfigs.joinToString(",") - ) - from(forgeManifest) - } - - from(commonProject.sourceSets.main.map { it.output }) - from(commonProject.sourceSets.named("mixins").map {it.output }) - from(commonProject.sourceSets.named("accessors").map {it.output }) - from(commonProject.sourceSets.named("launch").map {it.output }) - - from(forgeLaunch.output) - from(forgeAccessors.output) - from(forgeMixins.output) - } - - val universalJar = register("universalJar", Jar::class) { - group = "build" - archiveClassifier.set("universal") - - manifest.from(forgeServicesShadowJar.manifest) - - from(forgeServicesShadowJar.archiveFile.map { zipTree(it) }) - - into("jars") { - from(shadowJar) - rename("spongeforge-(.*)-mod.jar", "spongeforge-mod.jar") - - from(forgeLangJar) - rename("spongeforge-(.*)-lang.jar", "spongeforge-lang.jar") - } - } - - assemble { - dependsOn(universalJar) - } -} - -sourceSets { - main { - blossom.resources { - property("version", project.provider { project.version.toString() }) - property("description", project.description.toString()) - } - } -} - -afterEvaluate { - sourceSets.configureEach { - // Don't apply Mixin AP - configurations.named(annotationProcessorConfigurationName) { - exclude(group = "org.spongepowered", module = "mixin") - exclude(group = "net.fabricmc", module = "fabric-mixin-compile-extensions") - } - // And don't pass AP parameters - tasks.named(compileJavaTaskName, JavaCompile::class) { - val mixinApArgs = setOf("outRefMapFile", "defaultObfuscationEnv", "outMapFileNamedIntermediary", "inMapFileNamedIntermediary") - options.compilerArgs.removeIf { mixinApArgs.any { mixin -> it.contains(mixin)} } - } - } -} - -indraSpotlessLicenser { - licenseHeaderFile(rootProject.file("HEADER.txt")) - - property("name", "Sponge") - property("organization", organization) - property("url", projectUrl) -} - -publishing { - publications { - register("sponge", MavenPublication::class) { - artifact(tasks["universalJar"]) - - artifact(tasks["jar"]) - artifact(tasks["sourcesJar"]) - - artifact(tasks["forgeMixinsJar"]) - artifact(tasks["mixinsSourcesJar"]) - - artifact(tasks["forgeAccessorsJar"]) - artifact(tasks["accessorsSourcesJar"]) - - artifact(tasks["forgeLaunchJar"]) - artifact(tasks["launchSourcesJar"]) - - artifact(tasks["forgeAppLaunchJar"]) - artifact(tasks["applaunchSourcesJar"]) - - pom { - artifactId = project.name.lowercase() - this.name.set(project.name) - this.description.set(project.description) - this.url.set(projectUrl) - - licenses { - license { - this.name.set("MIT") - this.url.set("https://opensource.org/licenses/MIT") - } - } - scm { - connection.set("scm:git:git://github.com/SpongePowered/Sponge.git") - developerConnection.set("scm:git:ssh://github.com/SpongePowered/Sponge.git") - this.url.set(projectUrl) - } - } - } - } -} - -tasks.register("printConfigsHierarchy") { - group = "debug" - doLast { - configurations.forEach { conf: Configuration -> - val seen = mutableSetOf() - println("Parents of ${conf.name}:") - printParents(conf, "", seen) - } - } -} - -fun printParents(conf: Configuration, indent: String, seen: MutableSet) { - for (parent in conf.extendsFrom) { - if (parent in seen) { - continue - } - seen.add(parent) - println("$indent - ${parent.name}") - printParents(parent, indent + " ", seen) - } -} - -tasks.register("printConfigsResolution") { - group = "debug" - doLast { - configurations.forEach { conf: Configuration -> - println() - println("Artifacts of ${conf.name}:") - if (conf.isCanBeResolved) { - try { - conf.forEach { - println(it) - } - } catch (e: Exception) { - println("error") - } - } else { - println("not resolved") - } - } - } -} diff --git a/neoforge/gradle.properties b/neoforge/gradle.properties deleted file mode 100755 index 1c271bdaa7f..00000000000 --- a/neoforge/gradle.properties +++ /dev/null @@ -1,8 +0,0 @@ -name=SpongeNeoForge -implementation=NeoForge -description=The SpongeAPI implementation for MinecraftNeoForge - -neoForgeVersion=21.1.1 -loom.platform=neoforge -fabric.loom.dontRemap=true -mixinConfigs=mixins.spongeforge.accessors.json,mixins.spongeforge.api.json,mixins.spongeforge.inventory.json,mixins.spongeforge.core.json,mixins.spongeforge.tracker.json \ No newline at end of file diff --git a/neoforge/src/accessors/resources/mixins.spongeforge.accessors.json b/neoforge/src/accessors/resources/mixins.spongeforge.accessors.json deleted file mode 100755 index bf8a8bda19f..00000000000 --- a/neoforge/src/accessors/resources/mixins.spongeforge.accessors.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "required": true, - "parent": "mixins.sponge.parent.json", - "package": "org.spongepowered.forge.accessor", - "mixins": [ - ] -} \ No newline at end of file diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginDependencyConfigurable.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginDependencyConfigurable.java deleted file mode 100755 index a52ee64b10d..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginDependencyConfigurable.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.metadata; - -import net.neoforged.neoforgespi.language.IConfigurable; -import net.neoforged.neoforgespi.language.IModInfo; - -import org.spongepowered.plugin.metadata.PluginMetadata; -import org.spongepowered.plugin.metadata.model.PluginDependency; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -// ModVersion -public final class PluginDependencyConfigurable implements IConfigurable { - - private final PluginMetadata metadata; - private final PluginDependency dependency; - - public PluginDependencyConfigurable(final PluginMetadata metadata, final PluginDependency dependency) { - this.metadata = metadata; - this.dependency = dependency; - } - - @SuppressWarnings("unchecked") - @Override - public Optional getConfigElement(final String... key) { - if (key.length != 1) { - return Optional.empty(); - } - - return switch (key[0]) { - case "modId" -> (Optional) Optional.of(this.dependency.id()); - case "mandatory" -> (Optional) Optional.of(!this.dependency.optional()); - case "versionRange" -> (Optional) Optional.of(this.dependency.version().toString()); - case "ordering" -> (Optional) Optional.of(this.loadToOrdering(this.dependency.loadOrder()).toString()); - case "side" -> (Optional) Optional.of(IModInfo.DependencySide.BOTH.toString()); - default -> Optional.empty(); - }; - } - - @Override - public List getConfigList(final String... key) { - return Collections.emptyList(); - } - - private IModInfo.Ordering loadToOrdering(final PluginDependency.LoadOrder order) { - if (order == PluginDependency.LoadOrder.AFTER) { - return IModInfo.Ordering.AFTER; - } - - return IModInfo.Ordering.NONE; - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginFileConfigurable.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginFileConfigurable.java deleted file mode 100755 index acc6cbd7001..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginFileConfigurable.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.metadata; - -import net.neoforged.neoforgespi.language.IConfigurable; -import org.spongepowered.plugin.metadata.PluginMetadata; -import org.spongepowered.plugin.metadata.builtin.MetadataContainer; -import org.spongepowered.plugin.metadata.model.PluginDependency; - -import java.util.*; - -// ModFileInfo -public final class PluginFileConfigurable implements IConfigurable { - - private final MetadataContainer container; - - public PluginFileConfigurable(final MetadataContainer container) { - this.container = container; - } - - @SuppressWarnings("unchecked") - @Override - public Optional getConfigElement(final String... key) { - if (key.length < 1) { - return Optional.empty(); - } - - final String query = key[0]; - if (key.length != this.requiredConfigElements(query)) { - return Optional.empty(); - } - - if ("modLoader".equals(query)) { - return (Optional) Optional.of(this.container.loader().name()); - } - - if ("loaderVersion".equals(query)) { - return (Optional) Optional.of(this.container.loader().version().toString()); - } - - if ("license".equals(query)) { - return (Optional) Optional.of(this.container.license()); - } - - if (key.length == 2) { - final String plugin = key[1]; - final PluginMetadata metadata = this.container.metadata(plugin).orElse(null); - if (metadata == null) { - return Optional.empty(); - } - - if ("modproperties".equals(query)) { - return (Optional) Optional.of(metadata.properties()); - } - } - - return Optional.empty(); - } - - @Override - public List getConfigList(final String... key) { - if (key.length < 1) { - return Collections.emptyList(); - } - - final String query = key[0]; - if (key.length != this.requiredConfigElements(query)) { - return Collections.emptyList(); - } - - if ("mods".equals(query)) { - final Set metadataById = this.container.metadata(); - if (metadataById.isEmpty()) { - return Collections.emptyList(); - } - - final List metadataConfigurables = new ArrayList<>(); - metadataById.forEach((metadata) -> metadataConfigurables.add(new PluginMetadataConfigurable(metadata))); - return metadataConfigurables; - } - - if (key.length != 2) { - return Collections.emptyList(); - } - - final String plugin = key[1]; - final PluginMetadata metadata = this.container.metadata(plugin).orElse(null); - if (metadata == null) { - return Collections.emptyList(); - } - - if ("dependencies".equals(query)) { - - // TODO Should we inject a dependency on SpongeForge? - final Set dependencies = metadata.dependencies(); - if (dependencies.isEmpty()) { - return Collections.emptyList(); - } - - final List depConfigurables = new ArrayList<>(); - for (final PluginDependency dependency : dependencies) { - depConfigurables.add(new PluginDependencyConfigurable(metadata, dependency)); - } - - return depConfigurables; - } - - return Collections.emptyList(); - } - - private int requiredConfigElements(final String query) { - if ("dependencies".equals(query) || "modproperties".equals(query)) { - return 2; - } - - return 1; - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataConfigurable.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataConfigurable.java deleted file mode 100755 index 98567a39639..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataConfigurable.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.metadata; - -import net.neoforged.neoforgespi.language.IConfigurable; - -import org.spongepowered.plugin.metadata.PluginMetadata; - -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -// ModInfo -public final class PluginMetadataConfigurable implements IConfigurable { - - private final PluginMetadata metadata; - - public PluginMetadataConfigurable(final PluginMetadata metadata) { - this.metadata = metadata; - } - - @SuppressWarnings("unchecked") - @Override - public Optional getConfigElement(final String... key) { - if (key.length != 1) { - return Optional.empty(); - } - - return switch (key[0]) { - case "modId" -> Optional.of((T) this.metadata.id()); - case "version" -> Optional.of((T) this.metadata.version().toString()); - case "displayName" -> (Optional) this.metadata.name(); - case "description" -> (Optional) this.metadata.description(); - case "displayTest" -> Optional.of((T) "IGNORE_SERVER_VERSION"); - default -> Optional.empty(); - }; - } - - @Override - public List getConfigList(final String... key) { - return Collections.emptyList(); - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataUtils.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataUtils.java deleted file mode 100755 index 3a40bca1feb..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataUtils.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.metadata; - -import net.neoforged.fml.loading.moddiscovery.ModInfo; -import net.neoforged.neoforgespi.language.IModInfo; - -import org.spongepowered.plugin.metadata.PluginMetadata; -import org.spongepowered.plugin.metadata.builtin.StandardPluginMetadata; -import org.spongepowered.plugin.metadata.builtin.model.StandardPluginContributor; -import org.spongepowered.plugin.metadata.builtin.model.StandardPluginDependency; -import org.spongepowered.plugin.metadata.builtin.model.StandardPluginLinks; -import org.spongepowered.plugin.metadata.model.PluginDependency; - -import java.util.ArrayList; -import java.util.List; - -/** - * ModInfo cannot be mixed into as it is on the app class loader so this somewhat hacky util class will do... - */ -public final class PluginMetadataUtils { - - public static PluginMetadata modToPlugin(final ModInfo info) { - final StandardPluginMetadata.Builder builder = StandardPluginMetadata.builder(); - builder - .id(info.getModId()) - .name(info.getDisplayName()) - .version(info.getVersion().toString()) - .description(info.getDescription()) - .entrypoint("unknown") // TODO Map main class to mod id - .addContributor(StandardPluginContributor.builder() - .name(info.getConfigElement("authors").orElse("unknown").toString()) - .build()); - builder.links(StandardPluginLinks.builder().issues(info.getOwningFile().getIssueURL()).build()); - - final List dependencies = new ArrayList<>(); - for (final IModInfo.ModVersion dependency : info.getDependencies()) { - final StandardPluginDependency.Builder depBuilder = StandardPluginDependency.builder(); - depBuilder - .id(dependency.getModId()) - .loadOrder(PluginMetadataUtils.orderingToLoad(dependency.getOrdering())) - .version(dependency.getVersionRange().toString()) - ; - - dependencies.add(depBuilder.build()); - } - - if (!dependencies.isEmpty()) { - builder.dependencies(dependencies); - } - - return builder.build(); - } - - private static PluginDependency.LoadOrder orderingToLoad(final IModInfo.Ordering ordering) { - if (ordering == IModInfo.Ordering.AFTER) { - return PluginDependency.LoadOrder.AFTER; - } - return PluginDependency.LoadOrder.UNDEFINED; - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/ModFileParsers.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/ModFileParsers.java deleted file mode 100755 index fa4d4c3a8c8..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/ModFileParsers.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.moddiscovery; - -import cpw.mods.jarhandling.SecureJar; - -import net.neoforged.fml.loading.moddiscovery.ModFile; -import net.neoforged.fml.loading.moddiscovery.ModFileInfo; -import net.neoforged.fml.loading.moddiscovery.ModJarMetadata; -import net.neoforged.neoforgespi.language.IModFileInfo; -import net.neoforged.neoforgespi.locating.*; - -import org.spongepowered.common.applaunch.AppLaunch; -import org.spongepowered.common.applaunch.plugin.PluginPlatformConstants; -import org.spongepowered.forge.applaunch.loading.metadata.PluginFileConfigurable; -import org.spongepowered.plugin.metadata.builtin.MetadataContainer; -import org.spongepowered.plugin.metadata.builtin.MetadataParser; - -import java.io.Reader; -import java.lang.reflect.Constructor; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -public final class ModFileParsers { - private static Constructor modJarMetadataConstructor; - - static { - try { - ModFileParsers.modJarMetadataConstructor = ModJarMetadata.class.getDeclaredConstructor(); - ModFileParsers.modJarMetadataConstructor.setAccessible(true); - } catch (final Exception e) { - throw new RuntimeException(e); - } - } - - public static IModFileInfo parsePluginMetadata(final IModFile iModFile) { - final ModFile modFile = (ModFile) iModFile; - AppLaunch.logger().debug("Considering plugin file candidate {}", modFile.getFilePath()); - - final Path metadataFile = modFile.findResource(PluginPlatformConstants.METADATA_FILE_LOCATION); - if (Files.notExists(metadataFile)) { - AppLaunch.logger().debug("Plugin file '{}' is missing a 'sponge_plugins.json' metadata file in META-INF", modFile); - return null; - } - - try { - final MetadataContainer container; - try (final Reader reader = Files.newBufferedReader(metadataFile, StandardCharsets.UTF_8)) { - container = MetadataParser.read(reader); - } - - final PluginFileConfigurable config = new PluginFileConfigurable(container); - return new ModFileInfo(modFile, config, (info) -> {}, List.of()); - } catch (final Exception e) { - AppLaunch.logger().warn("Could not read metadata for plugin file '{}'", modFile, e); - return null; - } - } - - private static ModJarMetadata newModJarMetadata() { - try { - return modJarMetadataConstructor.newInstance(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public static ModFile newPluginInstance(final IModFileCandidateLocator locator, final Path... path) { - ModJarMetadata mjm = newModJarMetadata(); - ModFileInfoParser parser = ModFileParsers::parsePluginMetadata; - - ModFile modFile = new ModFile(SecureJar.from(path), parser, ModFileDiscoveryAttributes.DEFAULT.withLocator(locator)); - mjm.setModFile(modFile); - return modFile; - } - - public static ModFile newPluginInstance(final IDependencyLocator locator, final Path... path) { - ModJarMetadata mjm = newModJarMetadata(); - ModFileInfoParser parser = ModFileParsers::parsePluginMetadata; - - ModFile modFile = new ModFile(SecureJar.from(path), parser, ModFileDiscoveryAttributes.DEFAULT.withDependencyLocator(locator)); - mjm.setModFile(modFile); - return modFile; - } - - private ModFileParsers() { - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeDependencyLocator.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeDependencyLocator.java deleted file mode 100755 index 2757a0fde22..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeDependencyLocator.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.moddiscovery; - -import cpw.mods.modlauncher.Environment; -import cpw.mods.modlauncher.Launcher; - -import net.neoforged.fml.loading.FMLEnvironment; -import net.neoforged.fml.loading.moddiscovery.ModFile; -import net.neoforged.neoforgespi.locating.IDependencyLocator; -import net.neoforged.neoforgespi.locating.IDiscoveryPipeline; -import net.neoforged.neoforgespi.locating.IModFile; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import org.spongepowered.forge.applaunch.loading.moddiscovery.library.LibraryManager; -import org.spongepowered.forge.applaunch.transformation.SpongeForgeTransformationService; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -// works with ForgeProductionBootstrap to make this whole thing go -public class SpongeForgeDependencyLocator implements IDependencyLocator { - private static final Logger LOGGER = LogManager.getLogger(); - private final List modFiles = new ArrayList<>(); - - final Environment env = Launcher.INSTANCE.environment(); - private LibraryManager libraryManager = new LibraryManager( - env.getProperty(SpongeForgeTransformationService.Keys.CHECK_LIBRARY_HASHES.get()).orElse(true), - env.getProperty(SpongeForgeTransformationService.Keys.LIBRARIES_DIRECTORY.get()) - .orElseThrow(() -> new IllegalStateException("no libraries available")), - SpongeForgeModLocator.class.getResource("libraries.json")); - - @Override - public void scanMods(List loadedMods, IDiscoveryPipeline pipeline) { - // Add Sponge-specific libraries - if (FMLEnvironment.production) { - try { - this.libraryManager.validate(); - } catch (final Exception ex) { - throw new RuntimeException("Failed to download and validate Sponge libraries", ex); - } - this.libraryManager.finishedProcessing(); - - for (final LibraryManager.Library library : this.libraryManager.getAll().values()) { - final Path path = library.getFile(); - SpongeForgeDependencyLocator.LOGGER.debug("Proposing jar {} as a game library", path); - ModFile mod = ModFileParsers.newPluginInstance(this, path); - modFiles.add(mod); - } - } - } - - public List getModFiles() { - return modFiles; - } - -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeModLocator.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeModLocator.java deleted file mode 100755 index c03d28ac3a0..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeModLocator.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.moddiscovery; - -import com.google.common.collect.ImmutableMap; -import cpw.mods.modlauncher.Environment; -import cpw.mods.modlauncher.Launcher; - -import net.neoforged.fml.javafmlmod.FMLJavaModLanguageProvider; -import net.neoforged.neoforgespi.ILaunchContext; -import net.neoforged.neoforgespi.locating.IDiscoveryPipeline; -import net.neoforged.neoforgespi.locating.IModFile; -import net.neoforged.neoforgespi.locating.IModFileCandidateLocator; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import org.spongepowered.forge.applaunch.plugin.ForgePluginPlatform; - -import java.net.URI; -import java.net.URL; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -public final class SpongeForgeModLocator extends FMLJavaModLanguageProvider implements IModFileCandidateLocator { - private static final Logger LOGGER = LogManager.getLogger(); - private List modFiles = new ArrayList<>(); - - @Override - public void findCandidates(ILaunchContext context, IDiscoveryPipeline pipeline) { - try { - URL rootJar = SpongeForgeModLocator.class.getProtectionDomain().getCodeSource().getLocation(); - FileSystem fs = FileSystems.getFileSystem(rootJar.toURI()); // FML has already opened a file system for this jar - modFiles = Files.list(fs.getPath("jars")) - .filter(path -> path.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".jar")) - .map(path -> { - try { - URI jij = new URI("jij:" + path.toAbsolutePath().toUri().getRawSchemeSpecificPart()).normalize(); - final Map env = ImmutableMap.of("packagePath", path); - FileSystem jijFS = FileSystems.newFileSystem(jij, env); - return jijFS.getPath("/"); // root of the archive to load - } catch (Exception e) { - return null; - } - }).filter(path -> path != null).map(this::createMod).toList(); - } catch (Exception e) { - LOGGER.error("Failed to scan mod candidates", e); - } - } - - private IModFile createMod(Path path) { - return ModFileParsers.newPluginInstance(this, path); - } - - @Override - public String name() { - return "spongeneoforge"; - } - - //@Override - public void initArguments(Map arguments) { - final Environment env = Launcher.INSTANCE.environment(); - ForgePluginPlatform.bootstrap(env); - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/AsyncUtils.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/AsyncUtils.java deleted file mode 100755 index 61f212cf090..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/AsyncUtils.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.moddiscovery.library; - -import java.util.concurrent.Callable; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; - -final class AsyncUtils { - - private AsyncUtils() { - } - - static CompletableFuture asyncFailableFuture(final Callable action, final Executor executor) { - final CompletableFuture future = new CompletableFuture<>(); - executor.execute(() -> { - try { - future.complete(action.call()); - } catch (final Exception ex) { - future.completeExceptionally(ex); - } - }); - return future; - } - - @SuppressWarnings("unchecked") - static R sneakyThrow(final Throwable original) throws T { - throw (T) original; - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/InstallerUtils.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/InstallerUtils.java deleted file mode 100755 index 2c36eeff408..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/InstallerUtils.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.moddiscovery.library; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.channels.Channels; -import java.nio.channels.FileChannel; -import java.nio.channels.ReadableByteChannel; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; -import java.security.DigestInputStream; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -final class InstallerUtils { - - private static final Logger LOGGER = LogManager.getLogger(); - // From http://stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java - private static final char[] hexArray = "0123456789abcdef".toCharArray(); - - private InstallerUtils() { - } - - public static String toHexString(final byte[] bytes) { - final char[] hexChars = new char[bytes.length * 2]; - for (int j = 0; j < bytes.length; j++) { - final int v = bytes[j] & 0xFF; - hexChars[j * 2] = InstallerUtils.hexArray[v >>> 4]; - hexChars[j * 2 + 1] = InstallerUtils.hexArray[v & 0x0F]; - } - return new String(hexChars); - } - - public static boolean validateSha1(final String expectedHash, final Path path) throws IOException { - try (final InputStream is = Files.newInputStream(path)) { - return InstallerUtils.validateSha1(expectedHash, is); - } - } - - public static boolean validateSha1(final String expectedHash, final InputStream stream) throws IOException { - final MessageDigest digest; - try { - digest = MessageDigest.getInstance("SHA-1"); - } catch (final NoSuchAlgorithmException ex) { - throw new AssertionError(ex); // Guaranteed present by MessageDigest spec - } - - final byte[] buf = new byte[4096]; - int read; - - while ((read = stream.read(buf)) != -1) { - digest.update(buf,0, read); - } - - return expectedHash.equals(InstallerUtils.toHexString(digest.digest())); - } - - /** - * Downloads a file. - * - * @param url The file URL - * @param path The local path - * @throws IOException If there is a problem while downloading the file - */ - public static void download(final URL url, final Path path, final boolean requiresRequest) throws IOException { - Files.createDirectories(path.getParent()); - - final String name = path.getFileName().toString(); - - InstallerUtils.LOGGER.info("Downloading {}. This may take a while...", name); - InstallerUtils.LOGGER.info("URL -> <{}>", url); - - if (!requiresRequest) { - try (final ReadableByteChannel in = Channels.newChannel(url.openStream()); final FileChannel out = FileChannel.open(path, - StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) { - out.transferFrom(in, 0, Long.MAX_VALUE); - } - } else { - final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setRequestProperty("Content-Type", "application/json"); - connection.setRequestProperty("User-Agent", "Sponge-Downloader"); - - connection.connect(); - - try (final ReadableByteChannel in = Channels.newChannel(connection.getInputStream()); final FileChannel out = FileChannel.open(path, - StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) { - out.transferFrom(in, 0, Long.MAX_VALUE); - } - } - } - - /** - * Downloads a file and verify its digest. - * - * @param url The file URL - * @param path The local path - * @param expected The SHA-1 expected digest - * @throws IOException If there is a problem while downloading the file - */ - public static void downloadCheckHash(final URL url, final Path path, final MessageDigest digest, final String expected, - final boolean requiresRequest) throws IOException { - Files.createDirectories(path.getParent()); - - final String name = path.getFileName().toString(); - - InstallerUtils.LOGGER.info("Downloading {}. This may take a while...", name); - InstallerUtils.LOGGER.debug("URL -> <{}>", url); - - if (!requiresRequest) { - // Pipe the download stream into the file and compute the hash - try (final DigestInputStream stream = new DigestInputStream(url.openStream(), digest); final ReadableByteChannel in = Channels - .newChannel(stream); final FileChannel out = FileChannel.open(path, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) { - out.transferFrom(in, 0, Long.MAX_VALUE); - } - } else { - final HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("GET"); - connection.setRequestProperty("Content-Type", "application/json"); - connection.setRequestProperty("User-Agent", "Sponge-Downloader"); - - connection.connect(); - - // Pipe the download stream into the file and compute the hash - try (final DigestInputStream stream = new DigestInputStream(connection.getInputStream(), digest); final ReadableByteChannel in = Channels - .newChannel(stream); final FileChannel out = FileChannel.open(path, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)) { - out.transferFrom(in, 0, Long.MAX_VALUE); - } - } - - final String fileSha1 = InstallerUtils.toHexString(digest.digest()); - - if (expected.equalsIgnoreCase(fileSha1)) { - InstallerUtils.LOGGER.info("Successfully downloaded {} and verified checksum!", name); - } else { - Files.delete(path); - throw new IOException(String.format("Checksum verification failed: Expected '%s', got '%s'.", expected, fileSha1)); - } - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/LibraryManager.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/LibraryManager.java deleted file mode 100755 index 868427dce7b..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/LibraryManager.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.moddiscovery.library; - -import com.google.gson.Gson; -import com.google.gson.stream.JsonReader; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.spongepowered.forge.applaunch.loading.moddiscovery.library.model.sponge.Libraries; -import org.spongepowered.forge.applaunch.loading.moddiscovery.library.model.sponge.SonatypeResponse; - -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.security.MessageDigest; -import java.util.*; -import java.util.concurrent.*; - -// copied from SV -public final class LibraryManager { - - public static final String SPONGE_NEXUS_DOWNLOAD_URL = "https://repo.spongepowered.org/service/rest/v1/search/assets?md5=%s&maven" - + ".groupId=%s&maven.artifactId=%s&maven.baseVersion=%s&maven.extension=jar"; - private static final Logger LOGGER = LogManager.getLogger(); - - private final boolean checkLibraryHashes; - private final Path rootDirectory; - private final URL librariesUrl; - private final Map libraries; - private final ExecutorService preparationWorker; - - public LibraryManager(final boolean checkLibraryHashes, final Path rootDirectory, final URL librariesUrl) { - this.checkLibraryHashes = checkLibraryHashes; - this.rootDirectory = Objects.requireNonNull(rootDirectory, "rootDirectory"); - this.librariesUrl = Objects.requireNonNull(librariesUrl, "librariesUrl"); - - this.libraries = new LinkedHashMap<>(); - final int availableCpus = Runtime.getRuntime().availableProcessors(); - // We'll be performing mostly IO-blocking operations, so more threads will help us for now - // It might make sense to make this overridable eventually - this.preparationWorker = new ThreadPoolExecutor( - Math.min(Math.max(4, availableCpus * 2), 64), Integer.MAX_VALUE, - 60L, TimeUnit.SECONDS, - new LinkedBlockingQueue<>() // this is the number of tasks allowed to be waiting before the pool will spawn off a new thread (unbounded) - ); - } - - public Path getRootDirectory() { - return this.rootDirectory; - } - - public Map getAll() { - return Collections.unmodifiableMap(this.libraries); - } - - protected void addLibrary(final Library library) { - this.libraries.put(library.getName(), library); - } - - public void validate() throws Exception { - LibraryManager.LOGGER.info("Scanning and verifying libraries in '{}'. Please wait, this may take a moment...", this.rootDirectory); - - final Gson gson = new Gson(); - - final Libraries dependencies; - try (final JsonReader reader = new JsonReader(new InputStreamReader(this.librariesUrl.openStream(), StandardCharsets.UTF_8))) { - dependencies = gson.fromJson(reader, Libraries.class); - } - - final Set downloadedDeps = ConcurrentHashMap.newKeySet(); - final List> operations = new ArrayList<>(dependencies.dependencies.size()); - final Set failures = ConcurrentHashMap.newKeySet(); - - for (final Libraries.Dependency dependency : dependencies.dependencies.get("main")) { // todo: evaluate dep sections for forge - operations.add(AsyncUtils.asyncFailableFuture(() -> { - final String groupPath = dependency.group.replace(".", "/"); - final Path depDirectory = - this.rootDirectory.resolve(groupPath).resolve(dependency.module).resolve(dependency.version); - Files.createDirectories(depDirectory); - final Path depFile = depDirectory.resolve(dependency.module + "-" + dependency.version + ".jar"); - final MessageDigest md5 = MessageDigest.getInstance("MD5"); - - final boolean checkHashes = this.checkLibraryHashes; - - if (Files.exists(depFile)) { - if (!checkHashes) { - LibraryManager.LOGGER.info("Detected existing '{}', skipping hash checks...", depFile); - downloadedDeps.add(new Library(dependency.group + "-" + dependency.module, depFile)); - return null; - } - - // Pipe the download stream into the file and compute the SHA-1 - final byte[] bytes = Files.readAllBytes(depFile); - final String fileMd5 = InstallerUtils.toHexString(md5.digest(bytes)); - - if (dependency.md5.equals(fileMd5)) { - LibraryManager.LOGGER.debug("'{}' verified!", depFile); - } else { - LibraryManager.LOGGER.error("Checksum verification failed: Expected {}, {}. Deleting cached '{}'...", - dependency.md5, fileMd5, depFile); - Files.delete(depFile); - - final SonatypeResponse response = this.getResponseFor(gson, dependency); - - if (response.items.isEmpty()) { - failures.add("No data received from '" + new URL(String.format(LibraryManager.SPONGE_NEXUS_DOWNLOAD_URL, - dependency.md5, dependency.group, - dependency.module, dependency.version)) + "'!"); - return null; - } - final SonatypeResponse.Item item = response.items.get(0); - final URL url = item.downloadUrl; - - InstallerUtils.downloadCheckHash(url, depFile, md5, item.checksum.md5, true); - } - } else { - final SonatypeResponse response = this.getResponseFor(gson, dependency); - - if (response.items.isEmpty()) { - failures.add("No data received from '" + new URL(String.format(LibraryManager.SPONGE_NEXUS_DOWNLOAD_URL, - dependency.md5, dependency.group, - dependency.module, dependency.version)) + "'!"); - return null; - } - - final SonatypeResponse.Item item = response.items.get(0); - final URL url = item.downloadUrl; - - if (checkHashes) { - InstallerUtils.downloadCheckHash(url, depFile, md5, item.checksum.md5, true); - } else { - InstallerUtils.download(url, depFile, true); - } - } - - downloadedDeps.add(new Library(dependency.group + "-" + dependency.module, depFile)); - return null; - }, this.preparationWorker)); - } - - - CompletableFuture.allOf(operations.toArray(new CompletableFuture[0])).handle((result, err) -> { - if (err != null) { - failures.add(err.getMessage()); - LibraryManager.LOGGER.error("Failed to download library", err); - } - return result; - }).join(); - - if (!failures.isEmpty()) { - LibraryManager.LOGGER.error("Failed to download some libraries:"); - for (final String message : failures) { - LibraryManager.LOGGER.error(message); - } - System.exit(-1); - } - - for (final Library library : downloadedDeps) { - this.libraries.put(library.getName(), library); - } - } - - private SonatypeResponse getResponseFor(final Gson gson, final Libraries.Dependency dependency) throws IOException { - final URL requestUrl = new URL(String.format(LibraryManager.SPONGE_NEXUS_DOWNLOAD_URL, dependency.md5, dependency.group, - dependency.module, dependency.version)); - - final HttpURLConnection connection = (HttpURLConnection) requestUrl.openConnection(); - connection.setRequestMethod("GET"); - connection.setRequestProperty("Content-Type", "application/json"); - connection.setRequestProperty("User-Agent", "Sponge-Downloader"); - - connection.connect(); - - try (final JsonReader reader = new JsonReader(new InputStreamReader(connection.getInputStream()))) { - return gson.fromJson(reader, SonatypeResponse.class); - } - } - - public ExecutorService preparationWorker() { - return this.preparationWorker; - } - - public void finishedProcessing() { - if (this.preparationWorker.isTerminated()) { - return; - } - - this.preparationWorker.shutdown(); - boolean successful; - try { - successful = this.preparationWorker.awaitTermination(10L, TimeUnit.SECONDS); - } catch (final InterruptedException e) { - successful = false; - } - - if (!successful) { - LibraryManager.LOGGER.warn("Failed to shut down library preparation pool in 10 seconds, forcing shutdown now."); - this.preparationWorker.shutdownNow(); - } - } - - public static class Library { - - private final String name; - private final Path file; - - public Library(final String name, final Path file) { - this.name = name; - this.file = file; - } - - public String getName() { - return this.name; - } - - public Path getFile() { - return this.file; - } - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/Libraries.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/Libraries.java deleted file mode 100755 index f4fbc73b538..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/Libraries.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.moddiscovery.library.model.sponge; - -import java.util.List; -import java.util.Map; -import java.util.Objects; - -public final class Libraries { - - public Map> dependencies; - - public static final class Dependency { - - public String group, module, version, md5; - - @Override - public int hashCode() { - return Objects.hash(this.group, this.module); - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || this.getClass() != o.getClass()) { - return false; - } - final Dependency that = (Dependency) o; - return this.group.equals(that.group) && - this.module.equals(that.module); - } - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/SonatypeResponse.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/SonatypeResponse.java deleted file mode 100755 index 8ea4e7ce392..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/library/model/sponge/SonatypeResponse.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.moddiscovery.library.model.sponge; - -import java.net.URL; -import java.util.List; - -public final class SonatypeResponse { - - public List items; - public String continuationToken; - - public static final class Item { - - public URL downloadUrl; - public String path, id, repository, format; - public Checksum checksum; - } - - public static final class Checksum { - - public String sha1, md5; - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/EnvironmentPluginLocator.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/EnvironmentPluginLocator.java deleted file mode 100755 index 02b0b181508..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/EnvironmentPluginLocator.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.moddiscovery.locator; - -import net.neoforged.fml.javafmlmod.FMLJavaModLanguageProvider; -import net.neoforged.neoforgespi.ILaunchContext; -import net.neoforged.neoforgespi.language.ModFileScanData; -import net.neoforged.neoforgespi.locating.IDiscoveryPipeline; -import net.neoforged.neoforgespi.locating.IModFileCandidateLocator; - -import org.spongepowered.forge.applaunch.loading.moddiscovery.ModFileParsers; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; - -public final class EnvironmentPluginLocator extends FMLJavaModLanguageProvider implements IModFileCandidateLocator { - - @Override - public void findCandidates(ILaunchContext context, IDiscoveryPipeline pipeline) { - for(Path[] arrayPaths : getPluginsPaths()) for(Path path : arrayPaths) context.addLocated(path); - scanMods().forEach(scan -> { - scan.getIModInfoData().forEach(file -> { - pipeline.addModFile(file.getFile()); - context.addLocated(file.getFile().getFilePath()); - }); - }); - } - - //@Override - public List scanMods() { - final List modFiles = new ArrayList<>(); - for (final Path[] paths : getPluginsPaths()) { - ModFileScanData data = new ModFileScanData(); - data.addModFileInfo(ModFileParsers.newPluginInstance(this, paths).getModFileInfo()); - } - return modFiles; - } - - //@Override - protected ModFileScanData createMod(Path path) { - ModFileScanData data = new ModFileScanData(); - data.addModFileInfo(ModFileParsers.newPluginInstance(this, path).getModFileInfo()); - return data; - } - - @Override - public String name() { - return "environment plugin"; - } - - //@Override - public void initArguments(final Map arguments) { - } - - private static List getPluginsPaths() { - final String env = System.getenv("SPONGE_PLUGINS"); - if (env == null) { - return Collections.emptyList(); - } - - List plugins = new ArrayList<>(); - for (final String entry : env.split(";")) { - if (entry.isBlank()) { - continue; - } - plugins.add(Stream.of(entry.split("&")).map(Path::of).toArray(Path[]::new)); - } - - return plugins; - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/PluginsDirectoryLocator.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/PluginsDirectoryLocator.java deleted file mode 100755 index 8a1211aae7f..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/PluginsDirectoryLocator.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.loading.moddiscovery.locator; - -import cpw.mods.util.LambdaExceptionUtils; - -import net.neoforged.fml.javafmlmod.FMLJavaModLanguageProvider; -import net.neoforged.fml.loading.ModDirTransformerDiscoverer; -import net.neoforged.fml.loading.StringUtils; -import net.neoforged.fml.loading.moddiscovery.ModFile; -import net.neoforged.neoforgespi.ILaunchContext; -import net.neoforged.neoforgespi.language.ModFileScanData; -import net.neoforged.neoforgespi.locating.IDiscoveryPipeline; -import net.neoforged.neoforgespi.locating.IModFileCandidateLocator; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import org.spongepowered.common.applaunch.AppLaunch; -import org.spongepowered.forge.applaunch.loading.moddiscovery.ModFileParsers; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; - -public final class PluginsDirectoryLocator extends FMLJavaModLanguageProvider implements IModFileCandidateLocator { - private static final Logger LOGGER = LogManager.getLogger(); - - final List modFiles = new ArrayList<>(); - - @Override - public void findCandidates(ILaunchContext context, IDiscoveryPipeline pipeline) { - final List pluginDirectories = AppLaunch.pluginPlatform().pluginDirectories(); - - for (final Path paths : pluginDirectories) { - this.scanForModsIn(paths).forEach(this::addData); - } - } - - public List getScanData() { - return modFiles; - } - - private Stream scanForModsIn(final Path pluginsDirectory) { - - final List excluded = ModDirTransformerDiscoverer.allExcluded(); - return LambdaExceptionUtils.uncheck(() -> Files.list(pluginsDirectory)) - .filter((p) -> !excluded.contains(p) && StringUtils.toLowerCase(p.getFileName().toString()).endsWith(".jar")) - .sorted(Comparator.comparing((path) -> StringUtils.toLowerCase(path.getFileName().toString()))) - .map((p) -> ModFileParsers.newPluginInstance(this, p)) - .filter(ModFile::identifyMods); - } - - @Override - public String name() { - return "plugins directory"; - } - - //@Override - public void initArguments(final Map arguments) { - } - - private void addData(ModFile modFile) { - ModFileScanData data = new ModFileScanData(); - data.addModFileInfo(modFile.getModFileInfo()); - modFiles.add(data); - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/plugin/ForgePluginPlatform.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/plugin/ForgePluginPlatform.java deleted file mode 100755 index 6ba748612e1..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/plugin/ForgePluginPlatform.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.plugin; - -import cpw.mods.modlauncher.Environment; -import cpw.mods.modlauncher.api.IEnvironment; - -import net.neoforged.fml.loading.FMLPaths; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.spongepowered.common.applaunch.AppLaunch; -import org.spongepowered.common.applaunch.config.core.SpongeConfigs; -import org.spongepowered.common.applaunch.plugin.PluginPlatform; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public final class ForgePluginPlatform implements PluginPlatform { - - private static volatile boolean bootstrapped; - - private final Environment environment; - private final Logger logger; - private final List pluginDirectories; - - /** - * Bootstrap - * @param environment - * @return - */ - public static synchronized boolean bootstrap(final Environment environment) { - if (ForgePluginPlatform.bootstrapped) { - return false; - } - ForgePluginPlatform.bootstrapped = true; - final ForgePluginPlatform platform = new ForgePluginPlatform(environment); - AppLaunch.setPluginPlatform(platform); - platform.init(); - return true; - } - - private ForgePluginPlatform(final Environment environment) { - this.environment = environment; - this.logger = LogManager.getLogger("plugin"); - this.pluginDirectories = new ArrayList<>(); - - this.pluginDirectories.add(FMLPaths.MODSDIR.get()); - } - - @Override - public String version() { - return this.environment.getProperty(IEnvironment.Keys.VERSION.get()).orElse("dev"); - } - - @Override - public void setVersion(final String version) { - // NOOP - } - - @Override - public Logger logger() { - return this.logger; - } - - @Override - public Path baseDirectory() { - return this.environment.getProperty(IEnvironment.Keys.GAMEDIR.get()).orElse(Paths.get(".")); - } - - @Override - public void setBaseDirectory(final Path baseDirectory) { - // NOOP - } - - @Override - public List pluginDirectories() { - return Collections.unmodifiableList(this.pluginDirectories); - } - - @Override - public void setPluginDirectories(final List pluginDirectories) { - // NOOP - } - - // TODO: Zidane, how will this work with SF? - @Override - public String metadataFilePath() { - return null; - } - - @Override - public void setMetadataFilePath(final String metadataFilePath) { - // NOOP - } - - public void init() { - final Path alternativePluginsDirectory = Paths.get(SpongeConfigs.getCommon().get().general.pluginsDir.getParsed()); - try { - Files.createDirectories(alternativePluginsDirectory); - } catch (final IOException e) { - throw new RuntimeException(e); - } - - this.pluginDirectories.add(alternativePluginsDirectory); - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/ListenerTransformer.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/ListenerTransformer.java deleted file mode 100755 index 3990525693b..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/ListenerTransformer.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.transformation; - -import cpw.mods.modlauncher.api.*; -import net.neoforged.fml.loading.LoadingModList; -import net.neoforged.fml.loading.moddiscovery.ModFileInfo; -import net.neoforged.neoforgespi.language.ModFileScanData; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.objectweb.asm.Type; -import org.objectweb.asm.tree.*; - -import java.util.HashSet; -import java.util.Set; - -import static org.objectweb.asm.Opcodes.*; - -public class ListenerTransformer implements ITransformer { - - @NonNull - @Override - public ClassNode transform(final ClassNode input, final ITransformerVotingContext context) { - MethodNode clinit = null; - for (final MethodNode method : input.methods) { - if (method.name.equals("") && method.desc.equals("()V")) { - clinit = method; - break; - } - } - - if (clinit == null) { - clinit = new MethodNode(ACC_STATIC, "", "()V", null, null); - clinit.instructions.add(new InsnNode(RETURN)); - input.methods.add(clinit); - } - - - final InsnList list = new InsnList(); - list.add(new LdcInsnNode(Type.getObjectType(input.name))); - list.add(new MethodInsnNode(INVOKESTATIC, "java/lang/invoke/MethodHandles", "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", false)); - list.add(new MethodInsnNode(INVOKESTATIC, "org/spongepowered/forge/launch/event/ListenerLookups", "set", "(Ljava/lang/Class;Ljava/lang/invoke/MethodHandles$Lookup;)V")); - - clinit.instructions.insert(list); - - return input; - } - - @NonNull - @Override - public TransformerVoteResult castVote(final ITransformerVotingContext context) { - return context.getReason().equals(ITransformerActivity.CLASSLOADING_REASON) ? TransformerVoteResult.YES : TransformerVoteResult.NO; - } - - @Override - public Set> targets() { - final Type listenerType = Type.getType("Lorg/spongepowered/api/event/Listener;"); - - final Set listenerClasses = new HashSet<>(); - for (ModFileInfo fileInfo : LoadingModList.get().getModFiles()) { - for (ModFileScanData.AnnotationData annotation : fileInfo.getFile().getScanResult().getAnnotations()) { - if (listenerType.equals(annotation.annotationType())) { - listenerClasses.add(annotation.clazz()); - } - } - } - - final Set> targets = new HashSet<>(); - for (Type listener : listenerClasses) { - targets.add(Target.targetClass(listener.getInternalName())); - } - return targets; - } - - @Override - public TargetType getTargetType() { - return TargetType.CLASS; - } -} diff --git a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/SpongeForgeTransformationService.java b/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/SpongeForgeTransformationService.java deleted file mode 100755 index 0849a65b284..00000000000 --- a/neoforge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/SpongeForgeTransformationService.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.applaunch.transformation; - -import cpw.mods.jarhandling.SecureJar; -import cpw.mods.modlauncher.Environment; -import cpw.mods.modlauncher.Launcher; -import cpw.mods.modlauncher.api.*; - -import joptsimple.OptionSpec; -import joptsimple.OptionSpecBuilder; - -import net.neoforged.fml.loading.LoadingModList; -import net.neoforged.fml.loading.moddiscovery.ModFileInfo; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.transformers.modlauncher.AccessWidenerTransformationService; -import org.spongepowered.transformers.modlauncher.SuperclassChanger; - -import java.net.MalformedURLException; -import java.nio.file.Path; -import java.util.List; -import java.util.Set; -import java.util.function.BiFunction; -import java.util.function.Supplier; -import java.util.jar.Attributes; - -public class SpongeForgeTransformationService implements ITransformationService { - private static final Logger LOGGER = LogManager.getLogger(); - - private OptionSpec checkHashes; - private OptionSpec librariesDirectoryName; - - @NonNull - @Override - public String name() { - return "spongeforge"; - } - - @Override - public void arguments(final BiFunction argumentBuilder) { - this.checkHashes = argumentBuilder.apply("checkHashes", "Whether to check hashes when downloading libraries") - .withOptionalArg() - .ofType(Boolean.class) - .defaultsTo(true); - this.librariesDirectoryName = argumentBuilder.apply("librariesDir", "The directory to download SpongeForge libraries to") - .withOptionalArg() - .ofType(String.class) - .defaultsTo("sponge-libraries"); - } - - @Override - public void argumentValues(final OptionResult option) { - Launcher.INSTANCE.environment().computePropertyIfAbsent(Keys.CHECK_LIBRARY_HASHES.get(), $ -> option.value(this.checkHashes)); - Launcher.INSTANCE.environment().computePropertyIfAbsent(Keys.LIBRARIES_DIRECTORY.get(), - $ -> Launcher.INSTANCE.environment().getProperty(IEnvironment.Keys.GAMEDIR.get()) - .orElseThrow(() -> new IllegalStateException("No game directory was available")) - .resolve(option.value(this.librariesDirectoryName))); - } - - @Override - public void initialize(final IEnvironment environment) { - } - - @Override - public void onLoad(final IEnvironment env, final Set otherServices) { - } - - @Override - public List completeScan(IModuleLayerManager layerManager) { - final Environment env = Launcher.INSTANCE.environment(); - final AccessWidenerTransformationService accessWidener = env.getProperty(AccessWidenerTransformationService.INSTANCE.get()).orElse(null); - final SuperclassChanger superclassChanger = env.getProperty(SuperclassChanger.INSTANCE.get()).orElse(null); - - if (accessWidener != null || superclassChanger != null) { - // TODO move this inside modlauncher-transformers when updating SpongeVanilla to latest ModLauncher - for (ModFileInfo fileInfo : LoadingModList.get().getModFiles()) { - final SecureJar jar = fileInfo.getFile().getSecureJar(); - final Attributes attributes = jar.moduleDataProvider().getManifest().getMainAttributes(); - - if (accessWidener != null) { - final String awPaths = attributes.getValue("Access-Widener"); - if (awPaths != null) { - final String jarFileName = fileInfo.getFile().getFileName(); - LOGGER.debug("Registering access wideners from {} ...", jarFileName); - - for (final String awPath : awPaths.split(",")) { - try { - accessWidener.offerResource(jar.getPath(awPath).toUri().toURL(), awPath); - } catch (final MalformedURLException e) { - LOGGER.warn("Failed to register access widener {} from {}", awPath, jarFileName, e); - } - } - } - } - - if (superclassChanger != null) { - final String scPaths = attributes.getValue("Superclass-Transformer"); - if (scPaths != null) { - final String jarFileName = fileInfo.getFile().getFileName(); - LOGGER.debug("Registering superclass changers from {} ...", jarFileName); - - for (final String scPath : scPaths.split(",")) { - try { - superclassChanger.offerResource(jar.getPath(scPath).toUri().toURL(), scPath); - } catch (final MalformedURLException e) { - LOGGER.warn("Failed to register superclass changer {} from {}", scPath, jarFileName, e); - } - } - } - } - } - } - - return List.of(); - } - - @Override - public List> transformers() { - return List.of(new ListenerTransformer()); - } - - public static final class Keys { - - public static final Supplier> CHECK_LIBRARY_HASHES = IEnvironment.buildKey("sponge:check_library_hashes", Boolean.class); - public static final Supplier> LIBRARIES_DIRECTORY = IEnvironment.buildKey("sponge:libraries_directory", Path.class); - - private Keys() { - } - - } -} diff --git a/neoforge/src/applaunch/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService b/neoforge/src/applaunch/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService deleted file mode 100755 index ced7680d190..00000000000 --- a/neoforge/src/applaunch/resources/META-INF/services/cpw.mods.modlauncher.api.ITransformationService +++ /dev/null @@ -1 +0,0 @@ -org.spongepowered.forge.applaunch.transformation.SpongeForgeTransformationService diff --git a/neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IDependencyLocator b/neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IDependencyLocator deleted file mode 100755 index 97ede6493ca..00000000000 --- a/neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IDependencyLocator +++ /dev/null @@ -1 +0,0 @@ -org.spongepowered.forge.applaunch.loading.moddiscovery.SpongeForgeDependencyLocator \ No newline at end of file diff --git a/neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator b/neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator deleted file mode 100755 index ad02e10d0d0..00000000000 --- a/neoforge/src/applaunch/resources/META-INF/services/net.minecraftforge.forgespi.locating.IModLocator +++ /dev/null @@ -1,3 +0,0 @@ -org.spongepowered.forge.applaunch.loading.moddiscovery.SpongeForgeModLocator -org.spongepowered.forge.applaunch.loading.moddiscovery.locator.EnvironmentPluginLocator -org.spongepowered.forge.applaunch.loading.moddiscovery.locator.PluginsDirectoryLocator \ No newline at end of file diff --git a/neoforge/src/lang/java/org/spongepowered/forge/lang/provider/JavaPluginLanguageProvider.java b/neoforge/src/lang/java/org/spongepowered/forge/lang/provider/JavaPluginLanguageProvider.java deleted file mode 100755 index c0ecc3175d5..00000000000 --- a/neoforge/src/lang/java/org/spongepowered/forge/lang/provider/JavaPluginLanguageProvider.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.lang.provider; - -import cpw.mods.util.LambdaExceptionUtils; -import net.neoforged.fml.Logging; -import net.neoforged.fml.ModContainer; -import net.neoforged.fml.ModLoadingContext; -import net.neoforged.fml.ModLoadingException; -import net.neoforged.fml.javafmlmod.FMLJavaModLanguageProvider; -import net.neoforged.neoforgespi.language.IModInfo; -import net.neoforged.neoforgespi.language.IModLanguageLoader; -import net.neoforged.neoforgespi.language.ModFileScanData; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.objectweb.asm.Type; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.Map; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.stream.Collectors; - -public final class JavaPluginLanguageProvider extends FMLJavaModLanguageProvider { - - private static final Type PLUGIN_ANNOTATION = Type.getType("Lorg/spongepowered/plugin/builtin/jvm/Plugin;"); - - private final Logger logger; - - public JavaPluginLanguageProvider() { - this.logger = LogManager.getLogger(); - } - - @Override - public String name() { - return "java_plain"; - } -/* - @Override - public Consumer getFileVisitor() { - return scanResult -> { - final Map modTargetMap = scanResult.getAnnotations().stream() - .filter(ad -> ad.annotationType().equals(JavaPluginLanguageProvider.PLUGIN_ANNOTATION)) - .peek(ad -> this.logger.debug(Logging.SCAN, "Found @Plugin class {} with id {}", ad.clazz().getClassName(), ad.annotationData().get("value"))) - .map(ad -> new PluginTarget(ad.clazz().getClassName(), (String)ad.annotationData().get("value"))) - .collect(Collectors.toMap(PluginTarget::getPlugin, Function.identity(), (a,b)->a)); - scanResult.addLanguageLoader(modTargetMap); - }; - }*/ - - private static final class PluginTarget implements IModLanguageLoader { - - private final Logger logger; - private final String className; - private final String plugin; - - private PluginTarget(final String className, final String plugin) { - this.logger = LogManager.getLogger(); - this.className = className; - this.plugin = plugin; - } - - @Override - public ModContainer loadMod(final IModInfo info, final ModFileScanData modFileScanData, final ModuleLayer gameLayer) { - // The following is adapted from FMLJavaModLanguageProvider.FMLModTarget - - // This language class is loaded in the system level classloader - before the game even starts - // So we must treat container construction as an arms length operation, and load the container - // in the classloader of the game - the context classloader is appropriate here. - try { - final Class pluginContainer = Class.forName( - "org.spongepowered.forge.launch.plugin.PluginModContainer", true, Thread.currentThread().getContextClassLoader()); - this.logger.debug(Logging.LOADING, "Loading PluginModContainer from classloader {} - got {}", Thread.currentThread().getContextClassLoader(), pluginContainer.getClassLoader()); - final Constructor constructor = pluginContainer.getConstructor(IModInfo.class, String.class, ModFileScanData.class, ModuleLayer.class); - return (ModContainer) constructor.newInstance(info, className, modFileScanData, gameLayer); - } - // ALL exception handling has to be done through the classloader, because we're loaded in the wrong context, so any classes we just blind load will be in the wrong - // class loading context. Funky but works. - catch (final InvocationTargetException e) { - this.logger.fatal(Logging.LOADING, "Failed to build plugin", e); - final Class mle = (Class) LambdaExceptionUtils.uncheck(()->Class.forName("net.neoforged.fml.ModLoadingException", true, Thread.currentThread().getContextClassLoader())); - if (mle.isInstance(e.getTargetException())) { - throw mle.cast(e.getTargetException()); - } else { - final Class mls = (Class) LambdaExceptionUtils.uncheck(()->Class.forName("net.neoforged.fml.ModLoadingContext", true, Thread.currentThread().getContextClassLoader())); - throw LambdaExceptionUtils.uncheck(()->LambdaExceptionUtils.uncheck(()->mle.getConstructor(IModInfo.class, mls, String.class, Throwable.class)).newInstance(info, mls, "fml.modloading.failedtoloadmodclass", e)); - } - } - catch (final NoSuchMethodException | ClassNotFoundException | InstantiationException | IllegalAccessException e) { - this.logger.fatal(Logging.LOADING,"Unable to load PluginModContainer, excuse me?", e); - final Class mle = (Class)LambdaExceptionUtils.uncheck(()->Class.forName("net.neoforged.fml.ModLoadingException", true, Thread.currentThread().getContextClassLoader())); - final Class mls = (Class) LambdaExceptionUtils.uncheck(()->Class.forName("net.neoforged.fml.ModLoadingContext", true, Thread.currentThread().getContextClassLoader())); - throw LambdaExceptionUtils.uncheck(()->LambdaExceptionUtils.uncheck(()->mle.getConstructor(IModInfo.class, mls, String.class, Throwable.class)).newInstance(info, mls, "fml.modloading.failedtoloadmodclass", e)); - } - } - - public String getPlugin() { - return this.plugin; - } - - @Override - public String name() { - return ""; - } - - @Override - public String version() { - return ""; - } - } -} diff --git a/neoforge/src/lang/resources/META-INF/services/net.minecraftforge.forgespi.language.IModLanguageProvider b/neoforge/src/lang/resources/META-INF/services/net.minecraftforge.forgespi.language.IModLanguageProvider deleted file mode 100755 index 1f6b5fa2dfd..00000000000 --- a/neoforge/src/lang/resources/META-INF/services/net.minecraftforge.forgespi.language.IModLanguageProvider +++ /dev/null @@ -1 +0,0 @@ -org.spongepowered.forge.lang.provider.JavaPluginLanguageProvider \ No newline at end of file diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeLaunch.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeLaunch.java deleted file mode 100755 index 3c96f27755d..00000000000 --- a/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeLaunch.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.launch; - -import com.google.common.collect.Lists; -import com.google.inject.Guice; -import com.google.inject.Injector; -import com.google.inject.Module; -import com.google.inject.Stage; - -import net.neoforged.api.distmarker.Dist; -import net.neoforged.fml.loading.FMLLoader; -import net.neoforged.fml.loading.moddiscovery.ModInfo; -import org.spongepowered.common.applaunch.plugin.PluginPlatform; -import org.spongepowered.common.inject.SpongeCommonModule; -import org.spongepowered.common.inject.SpongeModule; -import org.spongepowered.common.launch.Launch; -import org.spongepowered.common.launch.mapping.SpongeMappingManager; -import org.spongepowered.forge.applaunch.loading.metadata.PluginMetadataUtils; -import org.spongepowered.forge.launch.inject.SpongeForgeModule; -import org.spongepowered.forge.launch.plugin.ForgePluginManager; -import org.spongepowered.plugin.PluginContainer; -import org.spongepowered.plugin.metadata.PluginMetadata; - -import java.util.List; - -public final class ForgeLaunch extends Launch { - - private final ForgePluginManager pluginManager; - private PluginContainer spongeForgePlugin; - private final ForgeMappingManager mappings = new ForgeMappingManager(); - - public ForgeLaunch(final PluginPlatform platform) { - super(platform); - this.pluginManager = new ForgePluginManager(); - } - - @Override - public boolean dedicatedServer() { - return FMLLoader.getDist() == Dist.DEDICATED_SERVER; - } - - @Override - public ForgePluginManager pluginManager() { - return this.pluginManager; - } - - @Override - public SpongeMappingManager mappingManager() { - return this.mappings; - } - - @Override - public Stage injectionStage() { - return FMLLoader.isProduction() ? Stage.PRODUCTION : Stage.DEVELOPMENT; - } - - @Override - public Injector createInjector() { - final List modules = Lists.newArrayList( - new SpongeModule(), - new SpongeCommonModule(), - new SpongeForgeModule() - ); - return Guice.createInjector(this.injectionStage(), modules); - } - - @Override - public PluginContainer platformPlugin() { - if (this.spongeForgePlugin == null) { - this.spongeForgePlugin = this.pluginManager().plugin("spongeforge").orElse(null); - - if (this.spongeForgePlugin == null) { - throw new RuntimeException("Could not find the plugin representing SpongeForge, this is a serious issue!"); - } - } - - return this.spongeForgePlugin; - } - - public PluginMetadata metadataForMod(final ModInfo info) { - return PluginMetadataUtils.modToPlugin(info); - } -} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeMappingManager.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeMappingManager.java deleted file mode 100755 index 5f994c49899..00000000000 --- a/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgeMappingManager.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.launch; - -import com.google.common.collect.ImmutableMap; -import net.neoforged.fml.loading.FMLEnvironment; -import org.spongepowered.common.launch.mapping.SpongeMappingManager; - -import java.util.Map; - -final class ForgeMappingManager implements SpongeMappingManager { - - // todo: something better - - private static final Map METHOD_MAPPINGS = ImmutableMap.of( - "neighborChanged", "func_220069_a", - "entityInside", "func_196262_a", - "stepOn", "func_176199_a", - "playerTouch", "func_70100_b_" - ); - - private static final Map FIELD_MAPPINGS = ImmutableMap.of( - ); - - @Override - public String toRuntimeClassName(final String srcName) { - return srcName; - } - - @Override - public String toRuntimeFieldName(final Class owner, final String srcName) { - return FMLEnvironment.production ? ForgeMappingManager.FIELD_MAPPINGS.getOrDefault(srcName, srcName) : srcName; - } - - @Override - public String toRuntimeMethodName(final Class owner, final String srcName, final Class... params) { - return FMLEnvironment.production ? ForgeMappingManager.METHOD_MAPPINGS.getOrDefault(srcName, srcName) : srcName; - } -} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgePlatform.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgePlatform.java deleted file mode 100755 index 0f538863862..00000000000 --- a/neoforge/src/launch/java/org/spongepowered/forge/launch/ForgePlatform.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.launch; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import org.spongepowered.api.MinecraftVersion; -import org.spongepowered.common.SpongePlatform; - -import java.util.Map; - -@Singleton -public final class ForgePlatform extends SpongePlatform { - - @Inject - public ForgePlatform(final MinecraftVersion minecraftVersion) { - super(minecraftVersion); - } - - @Override - public Map asMap() { - if (this.platformMap.isEmpty()) { - this.createPlatformMetadata(); - } - - return this.platformMap; - } -} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/ForgeEventBridge_Forge.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/ForgeEventBridge_Forge.java deleted file mode 100755 index 446b84fe464..00000000000 --- a/neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/ForgeEventBridge_Forge.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.launch.bridge.event; - -import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.event.Event; - -public interface ForgeEventBridge_Forge { - - /** - * Syncs the Sponge event to this Forge event - * - *

Note that a Sponge event might service multiple Forge events, so any - * syncing should be limited to the remit of this event only (i.e., if the - * event fires for multiple positions, the sync should only consider the - * positions this event is concerned with)

- * - * @param event The Sponge event - */ - void bridge$syncFrom(Event event); - - /** - * Syncs the Forge event to this Sponge event - * - *

Note that a Sponge event might service multiple Forge events, so any - * syncing should be limited to the remit of this event only (that is, this - * should only affect the Sponge event as far as the remit of this event goes, - * most likely not cancelling events but invalidating transactions.)

- * - * @param event The Sponge event - */ - void bridge$syncTo(Event event); - - /** - * Creates a Sponge event from this Forge event - */ - @Nullable Event bridge$createSpongeEvent(); - -} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/SpongeEventBridge_Forge.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/SpongeEventBridge_Forge.java deleted file mode 100755 index c8e4b64be36..00000000000 --- a/neoforge/src/launch/java/org/spongepowered/forge/launch/bridge/event/SpongeEventBridge_Forge.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.launch.bridge.event; - -import net.neoforged.bus.api.Event; -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.util.Collection; - -public interface SpongeEventBridge_Forge { - - /** - * Creates a Forge {@link Event} that must also implement - * {@link ForgeEventBridge_Forge} - not doing so will cause - * an error. - * - *

By default, this returns null.

- * - * @return The Forge event - */ - default @Nullable Collection bridge$createForgeEvents() { - return null; - } - - /** - * If there is a specialist dispatcher that we need to use for - * this given event, it can be defined here. - * - * @return The dispatcher to use. - * - * IEventBusInvokeDispatcher REMOVED IN NEOFORGE! - */ - /*default IEventBusInvokeDispatcher bridge$eventDispatcher() { - return EventListener::invoke; - }*/ - -} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/command/ForgeCommandManager.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/command/ForgeCommandManager.java deleted file mode 100755 index 035b9af6f1e..00000000000 --- a/neoforge/src/launch/java/org/spongepowered/forge/launch/command/ForgeCommandManager.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.launch.command; - -import com.google.common.base.Throwables; -import com.google.inject.Inject; -import com.google.inject.Provider; -import com.mojang.brigadier.ParseResults; -import com.mojang.brigadier.context.CommandContextBuilder; -import com.mojang.brigadier.context.ParsedArgument; -import com.mojang.brigadier.exceptions.CommandSyntaxException; - -import net.kyori.adventure.text.Component; - -import net.minecraft.commands.CommandSourceStack; - -import net.neoforged.bus.api.EventPriority; -import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.CommandEvent; -import org.spongepowered.api.Game; -import org.spongepowered.api.command.CommandCause; -import org.spongepowered.api.command.CommandResult; -import org.spongepowered.api.command.exception.CommandException; -import org.spongepowered.api.command.manager.CommandMapping; -import org.spongepowered.api.command.registrar.CommandRegistrar; -import org.spongepowered.common.command.brigadier.SpongeStringReader; -import org.spongepowered.common.command.manager.SpongeCommandManager; -import org.spongepowered.common.command.registrar.BrigadierBasedRegistrar; -import org.spongepowered.common.command.sponge.SpongeCommand; - -import java.util.Collections; - -public final class ForgeCommandManager extends SpongeCommandManager { - - @Inject - public ForgeCommandManager(final Game game, final Provider spongeCommand) { - super(game, spongeCommand); - } - - @Override - public CommandResult processCommand(final CommandCause cause, final CommandMapping mapping, - final String command, final String args) - throws CommandException { - final String original = args.isEmpty() ? command : (command + " " + args); // TODO SF 1.19.4, should we pass the original string as a param? - - final CommandRegistrar registrar = mapping.registrar(); - final boolean isBrig = registrar instanceof BrigadierBasedRegistrar; - final ParseResults parseResults; - if (isBrig) { - parseResults = this.getDispatcher().parse(original, (CommandSourceStack) cause); - } else { - // We have a non Brig registrar, so we just create a dummy result for mods to inspect. - final CommandContextBuilder contextBuilder = new CommandContextBuilder<>( - this.getDispatcher(), - (CommandSourceStack) cause, - this.getDispatcher().getRoot(), - 0); - contextBuilder.withCommand(ctx -> 1); - if (!args.isEmpty()) { - contextBuilder.withArgument("parsed", new ParsedArgument<>(command.length(), original.length(), args)); - } - parseResults = new ParseResults<>(contextBuilder, new SpongeStringReader(original), Collections.emptyMap()); - } - - // Relocated from Commands (injection short circuits it there) - final CommandEvent event = new CommandEvent(parseResults); - if (!NeoForge.EVENT_BUS.post(EventPriority.NORMAL, event).isCanceled()) { - if (event.getException() != null) { - Throwables.throwIfUnchecked(event.getException()); - } - // As per Forge, we just treat it as a zero success, and do nothing with it. - return CommandResult.builder().result(0).build(); - } - - if (isBrig) { - try { - return CommandResult.builder().result(this.getDispatcher().execute(parseResults)).build(); - } catch (CommandSyntaxException e) { - throw new CommandException(Component.empty(), e); // TODO SF 1.19.4, what message should we put there? - } - } else { - return mapping.registrar().process(cause, mapping, command, args); - } - } - -} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/event/ForgeEventManager.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/event/ForgeEventManager.java deleted file mode 100755 index 4f604e67cc0..00000000000 --- a/neoforge/src/launch/java/org/spongepowered/forge/launch/event/ForgeEventManager.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.launch.event; - -import com.google.inject.Singleton; - -import net.neoforged.bus.api.Event; -import net.neoforged.bus.api.EventListener; -import net.neoforged.bus.api.EventPriority; -import net.neoforged.bus.api.IEventBus; - -import org.checkerframework.checker.nullness.qual.Nullable; - -import org.spongepowered.common.event.manager.RegisteredListener; -import org.spongepowered.common.event.manager.SpongeEventManager; -import org.spongepowered.forge.launch.bridge.event.ForgeEventBridge_Forge; -import org.spongepowered.forge.launch.bridge.event.SpongeEventBridge_Forge; -import org.spongepowered.plugin.PluginContainer; - -import java.lang.invoke.MethodHandles; -import java.util.Collection; -import java.util.List; -import java.util.function.Consumer; - -@Singleton -public final class ForgeEventManager extends SpongeEventManager implements IEventBus { - - private final IEventBus wrappedEventBus; - - public ForgeEventManager(final IEventBus eventBus) { - this.wrappedEventBus = eventBus; - } - - // IEventBus - - @Override - public void register(final Object target) { - this.wrappedEventBus.register(target); - } - - @Override - public void addListener(final Consumer consumer) { - this.wrappedEventBus.addListener(consumer); - } - - @Override - public void addListener(Class eventType, Consumer consumer) { - - } - - @Override - public void addListener(final EventPriority priority, final Consumer consumer) { - this.wrappedEventBus.addListener(priority, consumer); - } - - @Override - public void addListener(EventPriority priority, Class eventType, Consumer consumer) { - this.wrappedEventBus.addListener(priority, eventType, consumer); - } - - @Override - public void addListener(final EventPriority priority, final boolean receiveCancelled, final Consumer consumer) { - this.wrappedEventBus.addListener(priority, receiveCancelled, consumer); - } - - @Override - public void addListener(final EventPriority priority, final boolean receiveCancelled, final Class eventType, final Consumer consumer) { - this.wrappedEventBus.addListener(priority, receiveCancelled, eventType, consumer); - } - - @Override - public void addListener(boolean receiveCanceled, Consumer consumer) { - this.wrappedEventBus.addListener(receiveCanceled, consumer); - } - - @Override - public void addListener(boolean receiveCanceled, Class eventType, Consumer consumer) { - this.wrappedEventBus.addListener(receiveCanceled, eventType, consumer); - } - - @Override - public void unregister(final Object object) { - this.wrappedEventBus.unregister(object); - } - - @Override - public T post(T event) { - return wrappedEventBus.post(event); - } - - @Override - public T post(EventPriority phase, T event) { - return wrappedEventBus.post(phase, event); - } - - @Override - public void start() { - this.wrappedEventBus.start(); - } - - // EventManager - - @Override - protected MethodHandles.@Nullable Lookup getLookup(final PluginContainer plugin, final Class handle) { - return ListenerLookups.get(handle); - } - - @Override - public boolean post(final org.spongepowered.api.event.Event event) { - final SpongeEventBridge_Forge eventBridge = ((SpongeEventBridge_Forge) event); - final @Nullable Collection forgeEvents = eventBridge.bridge$createForgeEvents(); - if (forgeEvents == null || forgeEvents.isEmpty()) { - // Do as SpongeVanilla does - Forge has no role to play here. - return super.post(event); - } - return this.postDualBus(event, forgeEvents); - } - - // Implementation - - private boolean postDualBus(final org.spongepowered.api.event.Event spongeEvent, final Collection forgeEvents) { - try (final NoExceptionClosable ignored = this.preparePost(spongeEvent)) { - final RegisteredListener.Cache listeners = this.getHandlerCache(spongeEvent); - final List> beforeModifications = listeners.beforeModifications(); - if (!beforeModifications.isEmpty()) { - // First, we fire the Sponge beforeModifications on the Sponge event - this.post(spongeEvent, beforeModifications); - - // Then we sync to the Forge events - for (final Event forgeEvent : forgeEvents) { - ((ForgeEventBridge_Forge) forgeEvent).bridge$syncFrom(spongeEvent); - } - } - // Then, we fire all our Forge events - for (final Event forgeEvent : forgeEvents) { - this.wrappedEventBus.post(forgeEvent); - // We must sync back the event's changes, if there are any. - // For complex events, this will be a partial sync. - ((ForgeEventBridge_Forge) forgeEvent).bridge$syncTo(spongeEvent); - } - - // and now we do our standard event listener stuff. - return this.post(spongeEvent, listeners.afterModifications()); - } - } -} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/event/ListenerLookups.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/event/ListenerLookups.java deleted file mode 100755 index 0ab48d288c8..00000000000 --- a/neoforge/src/launch/java/org/spongepowered/forge/launch/event/ListenerLookups.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.launch.event; - -import org.checkerframework.checker.nullness.qual.Nullable; - -import java.lang.invoke.MethodHandles; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -public class ListenerLookups { - private static final Map, MethodHandles.Lookup> lookups = new ConcurrentHashMap<>(); - - public static MethodHandles.@Nullable Lookup get(final Class listenerClass) { - return ListenerLookups.lookups.get(listenerClass); - } - - public static void set(final Class listenerClass, final MethodHandles.Lookup lookup) { - ListenerLookups.lookups.put(listenerClass, lookup); - } -} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/event/SpongeEventBus.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/event/SpongeEventBus.java deleted file mode 100755 index 69ff612bd03..00000000000 --- a/neoforge/src/launch/java/org/spongepowered/forge/launch/event/SpongeEventBus.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.launch.event; - -import net.neoforged.bus.*; -import net.neoforged.bus.api.*; - -import java.lang.reflect.Field; -import java.util.Objects; - -public final class SpongeEventBus extends EventBus { - - // I hope ya'll like reflection... - private static Field busIDField; - private static Field exceptionHandlerField; - private static Field trackPhasesField; - private static Field shutdownField; - private static Field baseTypeField; - private static Field checkTypesOnDispatchField; - - static { - try { - SpongeEventBus.busIDField = EventBus.class.getDeclaredField("busID"); - SpongeEventBus.exceptionHandlerField = EventBus.class.getDeclaredField("exceptionHandler"); - SpongeEventBus.trackPhasesField = EventBus.class.getDeclaredField("trackPhases"); - SpongeEventBus.shutdownField = EventBus.class.getDeclaredField("shutdown"); - SpongeEventBus.baseTypeField = EventBus.class.getDeclaredField("baseType"); - SpongeEventBus.checkTypesOnDispatchField = EventBus.class.getDeclaredField("checkTypesOnDispatch"); - - } catch (final Exception ex) { - // Burn this to the ground - throw new RuntimeException(ex); - } - } - - // reflected fields that are stored again to prevent multiple reflection calls - private final int rbusID; - private final IEventExceptionHandler rexceptionHandler; - private final boolean rtrackPhases; - private boolean rshutdown; - private final Class rbaseType; - private final boolean rcheckTypesOnDispatch; - - public SpongeEventBus(final BusBuilderImpl busBuilder) { - super(busBuilder); - - // Sponge Start - I hope ya'll still like reflection - try { - SpongeEventBus.busIDField.setAccessible(true); - SpongeEventBus.exceptionHandlerField.setAccessible(true); - SpongeEventBus.trackPhasesField.setAccessible(true); - SpongeEventBus.shutdownField.setAccessible(true); - SpongeEventBus.baseTypeField.setAccessible(true); - SpongeEventBus.checkTypesOnDispatchField.setAccessible(true); - - this.rbusID = SpongeEventBus.busIDField.getInt(this); - this.rexceptionHandler = (IEventExceptionHandler) SpongeEventBus.exceptionHandlerField.get(this); - this.rtrackPhases = SpongeEventBus.trackPhasesField.getBoolean(this); - this.rshutdown = SpongeEventBus.shutdownField.getBoolean(this); - this.rbaseType = (Class) SpongeEventBus.baseTypeField.get(this); - this.rcheckTypesOnDispatch = SpongeEventBus.checkTypesOnDispatchField.getBoolean(this); - - SpongeEventBus.busIDField.setAccessible(false); - SpongeEventBus.exceptionHandlerField.setAccessible(false); - SpongeEventBus.trackPhasesField.setAccessible(false); - SpongeEventBus.shutdownField.setAccessible(false); - SpongeEventBus.baseTypeField.setAccessible(false); - SpongeEventBus.checkTypesOnDispatchField.setAccessible(false); - } catch (final Exception ex) { - // Burn this to the ground again - throw new RuntimeException(ex); - } - // Sponge End - } - - @Override - public void start() { - super.start(); - this.rshutdown = false; - } -} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/inject/SpongeForgeModule.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/inject/SpongeForgeModule.java deleted file mode 100755 index fa24af48809..00000000000 --- a/neoforge/src/launch/java/org/spongepowered/forge/launch/inject/SpongeForgeModule.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.launch.inject; - -import com.google.inject.AbstractModule; - -import net.neoforged.neoforge.common.NeoForge; - -import org.spongepowered.api.Platform; -import org.spongepowered.api.event.EventManager; -import org.spongepowered.common.command.manager.SpongeCommandManager; -import org.spongepowered.forge.launch.ForgePlatform; -import org.spongepowered.forge.launch.command.ForgeCommandManager; -import org.spongepowered.forge.launch.event.ForgeEventManager; - -public final class SpongeForgeModule extends AbstractModule { - - @Override - protected void configure() { - this.bind(Platform.class).to(ForgePlatform.class); - this.bind(EventManager.class).toProvider(() -> (ForgeEventManager) NeoForge.EVENT_BUS); - this.bind(SpongeCommandManager.class).to(ForgeCommandManager.class); - } - -} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginContainer.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginContainer.java deleted file mode 100755 index ebdbd9999a0..00000000000 --- a/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginContainer.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.launch.plugin; - -import com.google.common.collect.MapMaker; -import net.neoforged.fml.ModContainer; -import net.neoforged.fml.loading.moddiscovery.ModInfo; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.spongepowered.common.launch.Launch; -import org.spongepowered.forge.launch.ForgeLaunch; -import org.spongepowered.plugin.PluginContainer; -import org.spongepowered.plugin.metadata.PluginMetadata; - -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -public class ForgePluginContainer implements PluginContainer { - private final ModContainer modContainer; - - private Logger logger; - private PluginMetadata pluginMetadata; - private Object instance; // Find a way to get the instance of a plugin/mod from NeoForge - - ForgePluginContainer(final ModContainer modContainer) { - this.modContainer = modContainer; - } - - public ModContainer getModContainer() { - return this.modContainer; - } - - @Override - public PluginMetadata metadata() { - if (this.pluginMetadata == null) { - this.pluginMetadata = ((ForgeLaunch) Launch.instance()).metadataForMod((ModInfo) this.modContainer.getModInfo()); - } - return this.pluginMetadata; - } - - @Override - public Logger logger() { - if (this.logger == null) { - this.logger = LogManager.getLogger(this.modContainer.getModId()); - } - return this.logger; - } - - @Override - public Optional locateResource(URI relative) { - Objects.requireNonNull(relative, "relative"); - - final ClassLoader classLoader = this.modContainer.getClass().getClassLoader(); - final URL resolved = classLoader.getResource(relative.getPath()); - try { - if (resolved == null) { - return Optional.empty(); - } - return Optional.of(resolved.toURI()); - } catch (final URISyntaxException ignored) { - return Optional.empty(); - } - } - - @Override - public Object instance() { - return instance; - } - - private static final Map containers = new MapMaker().weakKeys().makeMap(); - - public static ForgePluginContainer of(final ModContainer modContainer) { - return containers.computeIfAbsent(modContainer, ForgePluginContainer::new); - } -} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginManager.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginManager.java deleted file mode 100755 index 0c571c66c94..00000000000 --- a/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginManager.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.launch.plugin; - -import com.google.common.collect.ImmutableList; -import com.google.inject.Singleton; -import net.neoforged.fml.ModList; -import net.neoforged.fml.common.Mod; -import org.spongepowered.common.launch.plugin.SpongePluginManager; -import org.spongepowered.plugin.PluginContainer; -import org.spongepowered.plugin.builtin.jvm.Plugin; - -import java.util.Collection; -import java.util.Objects; -import java.util.Optional; - -@Singleton -@SuppressWarnings("unchecked") -public final class ForgePluginManager implements SpongePluginManager { - - @Override - public Optional fromInstance(final Object instance) { - Objects.requireNonNull(instance, "instance"); - if(instance.getClass().isAnnotationPresent(Plugin.class)) return plugin(instance.getClass().getAnnotation(Plugin.class).value()); - if(instance.getClass().isAnnotationPresent(Mod.class)) return plugin(instance.getClass().getAnnotation(Mod.class).value()); - return Optional.empty(); - } - - @Override - public Optional plugin(final String id) { - return ModList.get().getModContainerById(Objects.requireNonNull(id, "id")).map(ForgePluginContainer::of); - } - - @Override - public Collection plugins() { - final ImmutableList.Builder builder = ImmutableList.builder(); - ModList.get().forEachModInOrder(mod -> builder.add(ForgePluginContainer.of(mod))); - return builder.build(); - } -} diff --git a/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/PluginModContainer.java b/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/PluginModContainer.java deleted file mode 100755 index 73f92ca0389..00000000000 --- a/neoforge/src/launch/java/org/spongepowered/forge/launch/plugin/PluginModContainer.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.launch.plugin; - -import com.google.inject.Injector; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.EventBusErrorMessage; -import net.minecraftforge.eventbus.api.BusBuilder; -import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.eventbus.api.IEventListener; -import net.minecraftforge.fml.Logging; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.ModLoadingException; -import net.minecraftforge.fml.ModLoadingStage; -import net.minecraftforge.fml.event.IModBusEvent; -import net.minecraftforge.fml.javafmlmod.AutomaticEventSubscriber; -import net.minecraftforge.forgespi.language.IModInfo; -import net.minecraftforge.forgespi.language.ModFileScanData; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.spongepowered.common.inject.plugin.PluginModule; -import org.spongepowered.common.launch.Launch; -import org.spongepowered.forge.launch.event.ForgeEventManager; -import org.spongepowered.plugin.PluginContainer; - -import java.util.Optional; - -// Spongified FMLModContainer -public final class PluginModContainer extends ModContainer { - private static final Logger LOGGER = LogManager.getLogger(); - - private final ModFileScanData scanResults; - private final IEventBus eventBus; - private Object modInstance; - private final Class modClass; - - public PluginModContainer(IModInfo info, String className, ModFileScanData modFileScanResults, ModuleLayer gameLayer) { - super(info); - LOGGER.debug(Logging.LOADING, "Creating PluginModContainer instance for {}", className); - this.scanResults = modFileScanResults; - this.activityMap.put(ModLoadingStage.CONSTRUCT, this::constructPlugin); - this.eventBus = BusBuilder.builder().setExceptionHandler(this::onEventFailed).setTrackPhases(false).markerType(IModBusEvent.class).useModLauncher().build(); - this.configHandler = Optional.of(ce -> this.eventBus.post(ce.self())); - this.contextExtension = () -> null; - - try { - Module module = gameLayer.findModule(info.getOwningFile().moduleName()).orElseThrow(); - modClass = Class.forName(module, className); - LOGGER.trace(Logging.LOADING, "Loaded modclass {} with {}", modClass.getName(), modClass.getClassLoader()); - } catch (Throwable e) { - LOGGER.error(Logging.LOADING, "Failed to load class {}", className, e); - throw new ModLoadingException(info, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadmodclass", e); - } - } - - private void onEventFailed(IEventBus iEventBus, Event event, IEventListener[] iEventListeners, int i, Throwable throwable) { - LOGGER.error(new EventBusErrorMessage(event, i, iEventListeners, throwable)); - } - - private void constructPlugin() { - try { - LOGGER.trace(Logging.LOADING, "Loading plugin instance {} of type {}", getModId(), this.modClass.getName()); - - final PluginContainer pluginContainer = ForgePluginContainer.of(this); - final Injector childInjector = Launch.instance().lifecycle().platformInjector().createChildInjector(new PluginModule(pluginContainer, this.modClass)); - this.modInstance = childInjector.getInstance(this.modClass); - ((ForgeEventManager) MinecraftForge.EVENT_BUS).registerListeners(pluginContainer, this.modInstance); - - LOGGER.trace(Logging.LOADING, "Loaded plugin instance {} of type {}", getModId(), this.modClass.getName()); - } catch (Throwable e) { - LOGGER.error(Logging.LOADING, "Failed to create plugin instance. PluginID: {}, class {}", getModId(), this.modClass.getName(), e); - throw new ModLoadingException(this.modInfo, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadmod", e, this.modClass); - } - - try { - LOGGER.trace(Logging.LOADING, "Injecting Automatic event subscribers for {}", getModId()); - AutomaticEventSubscriber.inject(this, this.scanResults, this.modClass.getClassLoader()); - LOGGER.trace(Logging.LOADING, "Completed Automatic event subscribers for {}", getModId()); - } catch (Throwable e) { - LOGGER.error(Logging.LOADING, "Failed to register automatic subscribers. PluginID: {}, class {}", getModId(), this.modClass.getName(), e); - throw new ModLoadingException(this.modInfo, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadmod", e, this.modClass); - } - } - - @Override - public boolean matches(Object mod) { - return mod == this.modInstance; - } - - @Override - public Object getMod() { - return this.modInstance; - } - - @Override - protected void acceptEvent(final T e) { - try { - LOGGER.trace(Logging.LOADING, "Firing event for modid {} : {}", this.getModId(), e); - this.eventBus.post(e); - LOGGER.trace(Logging.LOADING, "Fired event for modid {} : {}", this.getModId(), e); - } catch (Throwable t) { - LOGGER.error(Logging.LOADING, "Caught exception during event {} dispatch for modid {}", e, this.getModId(), t); - throw new ModLoadingException(this.modInfo, this.modLoadingStage, "fml.modloading.errorduringevent", t); - } - } -} diff --git a/neoforge/src/main/java/org/spongepowered/forge/ForgeClient.java b/neoforge/src/main/java/org/spongepowered/forge/ForgeClient.java deleted file mode 100755 index 481345f3c55..00000000000 --- a/neoforge/src/main/java/org/spongepowered/forge/ForgeClient.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge; - -import org.spongepowered.common.client.SpongeClient; - -public interface ForgeClient extends ForgeEngine, SpongeClient { - -} diff --git a/neoforge/src/main/java/org/spongepowered/forge/ForgeEngine.java b/neoforge/src/main/java/org/spongepowered/forge/ForgeEngine.java deleted file mode 100755 index 4ca3dfe8832..00000000000 --- a/neoforge/src/main/java/org/spongepowered/forge/ForgeEngine.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge; - -import org.spongepowered.common.SpongeEngine; - -public interface ForgeEngine extends SpongeEngine { -} diff --git a/neoforge/src/main/java/org/spongepowered/forge/ForgeServer.java b/neoforge/src/main/java/org/spongepowered/forge/ForgeServer.java deleted file mode 100755 index d953faf6105..00000000000 --- a/neoforge/src/main/java/org/spongepowered/forge/ForgeServer.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge; - -import org.spongepowered.common.SpongeServer; -import org.spongepowered.forge.world.server.ForgeWorldManager; - -public interface ForgeServer extends ForgeEngine, SpongeServer { - - @Override - ForgeWorldManager worldManager(); -} diff --git a/neoforge/src/main/java/org/spongepowered/forge/SpongeAPIMod.java b/neoforge/src/main/java/org/spongepowered/forge/SpongeAPIMod.java deleted file mode 100755 index dbfdcc9ea0b..00000000000 --- a/neoforge/src/main/java/org/spongepowered/forge/SpongeAPIMod.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge; - -import net.neoforged.fml.common.Mod; - -@Mod("spongeapi") -public class SpongeAPIMod { -} diff --git a/neoforge/src/main/java/org/spongepowered/forge/SpongeForgeMod.java b/neoforge/src/main/java/org/spongepowered/forge/SpongeForgeMod.java deleted file mode 100755 index a1e2ba478c9..00000000000 --- a/neoforge/src/main/java/org/spongepowered/forge/SpongeForgeMod.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge; - -import net.minecraft.client.Minecraft; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.MobCategory; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.Mod; -import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; -import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; -import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent; -import net.neoforged.neoforge.event.server.ServerAboutToStartEvent; -import net.neoforged.neoforge.event.server.ServerStartedEvent; -import net.neoforged.neoforge.event.server.ServerStoppingEvent; -import net.neoforged.neoforge.registries.RegisterEvent; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.spongepowered.api.Client; -import org.spongepowered.api.Server; -import org.spongepowered.api.Sponge; -import org.spongepowered.common.applaunch.config.core.ConfigHandle; -import org.spongepowered.common.entity.SpongeEntityTypes; -import org.spongepowered.common.entity.living.human.HumanEntity; -import org.spongepowered.common.hooks.PlatformHooks; -import org.spongepowered.common.launch.Launch; -import org.spongepowered.common.launch.Lifecycle; -import org.spongepowered.common.network.channel.SpongeChannelManager; -import org.spongepowered.common.network.packet.SpongePacketHandler; -import org.spongepowered.forge.hook.*; - -@Mod("spongeneoforge") -public final class SpongeForgeMod { - - private final Logger logger = LogManager.getLogger("SpongeNeoForge"); - - public SpongeForgeMod() { - // WorldPersistenceHooks.addHook(SpongeLevelDataPersistence.INSTANCE); // TODO SF 1.19.4 - - final IEventBus modBus = NeoForge.EVENT_BUS; - - // modBus: add all FML events with it - modBus.addListener(this::onCommonSetup); - modBus.addListener(this::onClientSetup); - modBus.addListener(this::onRegister); - modBus.addListener(this::onEntityAttributeCreationEvent); - - // annotation events, for non-FML things - modBus.register(this); - - // Set platform hooks as required - PlatformHooks.INSTANCE.setEventHooks(new ForgeEventHooks()); - PlatformHooks.INSTANCE.setWorldHooks(new ForgeWorldHooks()); - PlatformHooks.INSTANCE.setGeneralHooks(new ForgeGeneralHooks()); - PlatformHooks.INSTANCE.setChannelHooks(new ForgeChannelHooks()); - PlatformHooks.INSTANCE.setItemHooks(new ForgeItemHooks()); - } - - private void onCommonSetup(final FMLCommonSetupEvent event) { - final Lifecycle lifecycle = Launch.instance().lifecycle(); - lifecycle.callConstructEvent(); - lifecycle.callRegisterFactoryEvent(); - lifecycle.callRegisterBuilderEvent(); - lifecycle.callRegisterChannelEvent(); - lifecycle.establishGameServices(); - lifecycle.establishDataKeyListeners(); - - SpongePacketHandler.init((SpongeChannelManager) Sponge.channelManager()); - - this.logger.info("SpongeForge v{} initialized", Launch.instance().platformPlugin().metadata().version()); - } - - private void onClientSetup(final FMLClientSetupEvent event) { - final Client minecraft = (Client) Minecraft.getInstance(); - final Lifecycle lifecycle = Launch.instance().lifecycle(); - lifecycle.establishDataProviders(); - lifecycle.callRegisterDataEvent(); - lifecycle.establishClientRegistries(minecraft); - lifecycle.callStartingEngineEvent(minecraft); - } - - @SubscribeEvent - public void onServerAboutToStart(final ServerAboutToStartEvent event) { - // Save config now that registries have been initialized - ConfigHandle.setSaveSuppressed(false); - - final Lifecycle lifecycle = Launch.instance().lifecycle(); - lifecycle.establishServerServices(); - - lifecycle.establishServerFeatures(); - - lifecycle.establishServerRegistries((Server) event.getServer()); - lifecycle.callStartingEngineEvent((Server) event.getServer()); - } - - @SubscribeEvent - public void onServerStarted(final ServerStartedEvent event) { - final Lifecycle lifecycle = Launch.instance().lifecycle(); - lifecycle.callStartedEngineEvent((Server) event.getServer()); - - lifecycle.callLoadedGameEvent(); - } - - @SubscribeEvent - public void onServerStoppingEvent(final ServerStoppingEvent event) { - final Lifecycle lifecycle = Launch.instance().lifecycle(); - lifecycle.callStoppingEngineEvent((Server) event.getServer()); - } - - public void onRegister(RegisterEvent event) { - if (event.getRegistryKey() == BuiltInRegistries.ENTITY_TYPE) { - SpongeEntityTypes.HUMAN = EntityType.Builder.of(HumanEntity::new, MobCategory.MISC) - .noSave() - .sized(0.6F, 1.8F) - .clientTrackingRange(org.spongepowered.common.util.Constants.Entity.Player.TRACKING_RANGE) - .updateInterval(2) - .build("sponge:human") - ; - - event.register(BuiltInRegistries.ENTITY_TYPE.key(), helper -> helper.register(HumanEntity.KEY, SpongeEntityTypes.HUMAN)); - } - } - public void onEntityAttributeCreationEvent(final EntityAttributeCreationEvent event) { - event.put(SpongeEntityTypes.HUMAN, HumanEntity.createAttributes()); - } -} diff --git a/neoforge/src/main/java/org/spongepowered/forge/SpongeMod.java b/neoforge/src/main/java/org/spongepowered/forge/SpongeMod.java deleted file mode 100755 index b6524043c06..00000000000 --- a/neoforge/src/main/java/org/spongepowered/forge/SpongeMod.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge; - -import net.neoforged.fml.common.Mod; - -@Mod("sponge") -public class SpongeMod { -} diff --git a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeChannelHooks.java b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeChannelHooks.java deleted file mode 100755 index 82e03a96b29..00000000000 --- a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeChannelHooks.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.hook; - -import io.netty.buffer.Unpooled; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; -import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket; -import net.minecraft.network.protocol.common.custom.CustomPacketPayload; -import net.minecraft.resources.ResourceLocation; - -import org.spongepowered.api.network.EngineConnectionSide; -import org.spongepowered.api.network.channel.ChannelBuf; -import org.spongepowered.common.hooks.ChannelHooks; -import org.spongepowered.common.network.channel.SpongeChannelPayload; -import org.spongepowered.common.util.Constants; - -import java.util.function.Consumer; - -public final class ForgeChannelHooks implements ChannelHooks { - - @Override - public void registerPlatformChannels(final Consumer> consumer) { - } - - @Override - public Packet createRegisterPayload(final ChannelBuf payload, final EngineConnectionSide side) { - if (side == EngineConnectionSide.CLIENT) { - return ServerboundCustomPayloadPacket.CONFIG_STREAM_CODEC.decode(new FriendlyByteBuf(Unpooled.buffer()).writeResourceLocation((ResourceLocation) (Object) Constants.Channels.REGISTER_KEY).writeBytes(payload.array())); - } else if (side == EngineConnectionSide.SERVER) { - return ClientboundCustomPayloadPacket.CONFIG_STREAM_CODEC.decode(new FriendlyByteBuf(Unpooled.buffer()).writeResourceLocation((ResourceLocation) (Object) Constants.Channels.REGISTER_KEY).writeBytes(payload.array())); - } else { - throw new UnsupportedOperationException(); - } - } -} diff --git a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java deleted file mode 100755 index 681007ddbe2..00000000000 --- a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.hook; - -import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack;; -import net.neoforged.neoforge.event.entity.player.CriticalHitEvent; -import org.spongepowered.common.hooks.EventHooks; - -@SuppressWarnings("UnstableApiUsage") -public final class ForgeEventHooks implements EventHooks { - - @Override - public void callItemDestroyedEvent( - final Player player, final ItemStack stack, final InteractionHand hand - ) { - ForgeEventFactory.onPlayerDestroyItem(player, stack, InteractionHand.MAIN_HAND); - } - - @Override - public CriticalHitResult callCriticalHitEvent( - final Player player, final Entity targetEntity, final boolean isCriticalAttack, final float v - ) { - final CriticalHitEvent hitResult = ForgeHooks.getCriticalHit(player, targetEntity, isCriticalAttack, v + 1.0F); - if (hitResult != null) { - return new CriticalHitResult(true, hitResult.getDamageMultiplier() - 1.0F); - } - return new CriticalHitResult(false, v); - } -} diff --git a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeGeneralHooks.java b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeGeneralHooks.java deleted file mode 100755 index b5e184f002a..00000000000 --- a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeGeneralHooks.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.hook; - -import net.minecraft.network.chat.Component; -import net.minecraft.network.protocol.status.ServerStatus; - -import org.spongepowered.common.hooks.GeneralHooks; - -import java.util.Optional; - -public class ForgeGeneralHooks implements GeneralHooks { - - public ServerStatus createServerStatus(ServerStatus originalStatus, Component description, Optional players, Optional version, Optional favicon) { - return new ServerStatus(description, players, version, favicon, originalStatus.enforcesSecureChat(), originalStatus.isModded()); - } -} diff --git a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeItemHooks.java b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeItemHooks.java deleted file mode 100755 index 7698314caa6..00000000000 --- a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeItemHooks.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.hook; - -import org.spongepowered.common.hooks.ItemHooks; - -public class ForgeItemHooks implements ItemHooks { - -} diff --git a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java b/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java deleted file mode 100755 index 6da70fbb6e7..00000000000 --- a/neoforge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.hook; - -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; - -import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.level.LevelEvent; - -import org.spongepowered.common.hooks.WorldHooks; - -public class ForgeWorldHooks implements WorldHooks { - - @Override - public Entity getCustomEntityIfItem(final Entity entity) { - if (entity.getClass().equals(ItemEntity.class)) { - final ItemStack stack = ((ItemEntity) entity).getItem(); - final Item item = stack.getItem(); - if (item.hasCustomEntity(stack)) { - final Entity newEntity = item.createEntity(entity.level(), entity, stack); - if (newEntity != null) { - entity.remove(Entity.RemovalReason.DISCARDED); - return newEntity; - } - } - } - return null; - } - - @Override - public boolean isRestoringBlocks(final Level world) { - return world.restoringBlockSnapshots; - } - - @Override - public void postLoadWorld(final ServerLevel world) { - NeoForge.EVENT_BUS.post(new LevelEvent.Load(world)); - } -} diff --git a/neoforge/src/main/java/org/spongepowered/forge/world/server/ForgeWorldManager.java b/neoforge/src/main/java/org/spongepowered/forge/world/server/ForgeWorldManager.java deleted file mode 100755 index 13c510c27da..00000000000 --- a/neoforge/src/main/java/org/spongepowered/forge/world/server/ForgeWorldManager.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.world.server; - -import net.minecraft.server.MinecraftServer; -import org.spongepowered.common.world.server.SpongeWorldManager; - -public final class ForgeWorldManager extends SpongeWorldManager { - - public ForgeWorldManager(final MinecraftServer server) { - super(server); - } -} diff --git a/neoforge/src/main/resource-templates/META-INF/mods.toml b/neoforge/src/main/resource-templates/META-INF/mods.toml deleted file mode 100755 index b6a82ce527b..00000000000 --- a/neoforge/src/main/resource-templates/META-INF/mods.toml +++ /dev/null @@ -1,56 +0,0 @@ -modLoader="javafml" -loaderVersion="[52,)" -license="MIT License" - -issueTrackerURL="https://github.com/SpongePowered/Sponge/issues" - - -[[mods]] -modId="spongeforge" -version="{{ version }}" -displayName="SpongeForge" -displayTest="IGNORE_SERVER_VERSION" -credits="SpongePowered and Contributors" -authors="SpongePowered" -description = "{{ description }}" - -[[dependencies.spongeforge]] -modId="forge" -mandatory=true -versionRange="[52,)" -ordering="AFTER" -side="BOTH" - -[[dependencies.spongeforge]] -modId="sponge" -mandatory=true -versionRange="[{{ version }}]" -ordering="AFTER" -side="BOTH" - - -[[mods]] -modId="sponge" -version="{{ version }}" -displayName="Sponge" -displayTest="IGNORE_SERVER_VERSION" -credits="SpongePowered and Contributors" -authors="SpongePowered" -description="The SpongeAPI implementation targeting vanilla Minecraft and 3rd party platforms" - -[[dependencies.sponge]] -modId="spongeapi" -mandatory=true -versionRange="[12.0.0,)" -ordering="AFTER" -side="BOTH" - - -[[mods]] -modId="spongeapi" -version="12.0.0" -displayName="SpongeAPI" -displayTest="IGNORE_SERVER_VERSION" -credits="SpongePowered and Contributors" -authors="SpongePowered" -description="A Minecraft plugin API" diff --git a/neoforge/src/main/resources/forge.superclasschange b/neoforge/src/main/resources/forge.superclasschange deleted file mode 100755 index d6e2705c885..00000000000 --- a/neoforge/src/main/resources/forge.superclasschange +++ /dev/null @@ -1,3 +0,0 @@ -{ - "org.spongepowered.api.entity.ai.goal.AbstractGoal": "net.minecraft.world.entity.ai.goal.Goal" -} \ No newline at end of file diff --git a/neoforge/src/main/resources/pack.mcmeta b/neoforge/src/main/resources/pack.mcmeta deleted file mode 100755 index da6cf4608c3..00000000000 --- a/neoforge/src/main/resources/pack.mcmeta +++ /dev/null @@ -1,6 +0,0 @@ -{ - "pack": { - "description": "Resources for SpongeForge", - "pack_format": 34 - } -} \ No newline at end of file diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/api/minecraft/server/MinecraftServerMixin_Forge_API.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/api/minecraft/server/MinecraftServerMixin_Forge_API.java deleted file mode 100755 index 21feb542317..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/api/minecraft/server/MinecraftServerMixin_Forge_API.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.api.minecraft.server; - -import net.minecraft.server.MinecraftServer; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.forge.ForgeServer; -import org.spongepowered.forge.world.server.ForgeWorldManager; - -@Mixin(MinecraftServer.class) -public abstract class MinecraftServerMixin_Forge_API implements ForgeServer { - - private ForgeWorldManager forgeAPI$worldManager; - - @Inject(method = "", at = @At("TAIL")) - private void forgeAPI$setupSpongeFields(CallbackInfo ci) { - this.forgeAPI$worldManager = new ForgeWorldManager((MinecraftServer) (Object) this); - } - - @Override - public ForgeWorldManager worldManager() { - return this.forgeAPI$worldManager; - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/EventMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/EventMixin_Forge.java deleted file mode 100755 index 475f7c6bf71..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/EventMixin_Forge.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.api.event; - -import org.spongepowered.api.event.Event; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.forge.launch.bridge.event.SpongeEventBridge_Forge; - -@Mixin(value = Event.class, remap = false) -public interface EventMixin_Forge extends SpongeEventBridge_Forge { - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/block/ChangeBlockEvent_AllMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/block/ChangeBlockEvent_AllMixin_Forge.java deleted file mode 100755 index d9ad83e55f4..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/block/ChangeBlockEvent_AllMixin_Forge.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.api.event.block; - -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.event.level.BlockEvent; -import net.minecraftforge.eventbus.api.Event; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.block.transaction.BlockTransaction; -import org.spongepowered.api.block.transaction.Operation; -import org.spongepowered.api.block.transaction.Operations; -import org.spongepowered.api.event.block.ChangeBlockEvent; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.common.util.VecHelper; -import org.spongepowered.forge.launch.bridge.event.SpongeEventBridge_Forge; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@Mixin(value = ChangeBlockEvent.All.class, remap = false) -public interface ChangeBlockEvent_AllMixin_Forge extends SpongeEventBridge_Forge { - - @Override - default @Nullable Collection bridge$createForgeEvents() { - final ChangeBlockEvent.All thisEvent = ((ChangeBlockEvent.All) this); - final Player player = thisEvent.cause().first(Player.class).orElse(null); - final Operation breakOp = Operations.BREAK.get(); - - final List forgeEvents = new ArrayList<>(); - for (final BlockTransaction transaction : thisEvent.transactions()) { - if (player != null && transaction.operation() == breakOp) { - forgeEvents.add(new BlockEvent.BreakEvent((Level) thisEvent.world(), - VecHelper.toBlockPos(transaction.original().position()), - (BlockState) transaction.original().state(), player)); - } - // TODO: Other event types may go here - break is a PoC. - } - return forgeEvents; - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEntityWorldEvent_PreMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEntityWorldEvent_PreMixin_Forge.java deleted file mode 100755 index 30a236eefe4..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEntityWorldEvent_PreMixin_Forge.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.api.event.entity; - -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.Entity; -import net.minecraftforge.event.entity.EntityTravelToDimensionEvent; -import net.minecraftforge.eventbus.api.Event; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.event.entity.ChangeEntityWorldEvent; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.forge.mixin.core.api.event.EventMixin_Forge; - -import java.util.Collection; -import java.util.Collections; - -@Mixin(ChangeEntityWorldEvent.Pre.class) -public interface ChangeEntityWorldEvent_PreMixin_Forge extends EventMixin_Forge { - - @Override - default @Nullable Collection bridge$createForgeEvents() { - final ChangeEntityWorldEvent.Pre thisEvent = (ChangeEntityWorldEvent.Pre) this; - return Collections.singleton( - new EntityTravelToDimensionEvent((Entity) thisEvent.entity(), ((ServerLevel) thisEvent.destinationWorld()).dimension())); - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEventWorldEvent_PostMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEventWorldEvent_PostMixin_Forge.java deleted file mode 100755 index f85995d0727..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEventWorldEvent_PostMixin_Forge.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.api.event.entity; - -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.eventbus.api.Event; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.event.entity.ChangeEntityWorldEvent; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.forge.mixin.core.api.event.EventMixin_Forge; - -import java.util.Collection; -import java.util.Collections; - -@Mixin(ChangeEntityWorldEvent.Post.class) -public interface ChangeEventWorldEvent_PostMixin_Forge extends EventMixin_Forge { - - @Override - default @Nullable Collection bridge$createForgeEvents() { - if (((ChangeEntityWorldEvent.Post) this).entity() instanceof ServerPlayer) { - final ServerPlayer player = (ServerPlayer) ((ChangeEntityWorldEvent.Post) this).entity(); - - return Collections.singletonList(new PlayerEvent.PlayerChangedDimensionEvent(player, - ((ServerLevel) ((ChangeEntityWorldEvent.Post) this).originalWorld()).dimension(), - ((ServerLevel) ((ChangeEntityWorldEvent.Post) this).destinationWorld()).dimension())); - } - return null; - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/MinecraftMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/MinecraftMixin_Forge.java deleted file mode 100755 index 1ea4074660c..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/MinecraftMixin_Forge.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.client; - -import net.minecraft.client.Minecraft; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.common.bridge.client.MinecraftBridge; -import org.spongepowered.common.entity.player.ClientType; -import org.spongepowered.forge.ForgeClient; - -@Mixin(Minecraft.class) -public abstract class MinecraftMixin_Forge implements ForgeClient, MinecraftBridge { - - @Override - public ClientType bridge$getClientType() { - return ClientType.SPONGE_FORGE; - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/main/MainMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/main/MainMixin_Forge.java deleted file mode 100755 index d98d8d5bb53..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/client/main/MainMixin_Forge.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.client.main; - -import net.minecraft.client.main.Main; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.common.applaunch.AppLaunch; -import org.spongepowered.common.applaunch.plugin.PluginPlatform; -import org.spongepowered.common.launch.Launch; -import org.spongepowered.forge.launch.ForgeLaunch; - -@Mixin(Main.class) -public abstract class MainMixin_Forge { - - @Inject(method = "", at = @At("RETURN")) - private static void forge$initLaunch(final CallbackInfo ci) { - if (Launch.instance() != null) { - return; - } - final PluginPlatform pluginPlatform = AppLaunch.pluginPlatform(); - final ForgeLaunch launch = new ForgeLaunch(pluginPlatform); - Launch.setInstance(launch); - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/commands/CommandsMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/commands/CommandsMixin_Forge.java deleted file mode 100755 index 94dbf3edd68..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/commands/CommandsMixin_Forge.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.commands; - -import com.mojang.brigadier.Command; -import com.mojang.brigadier.suggestion.SuggestionProvider; -import com.mojang.brigadier.tree.CommandNode; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.commands.SharedSuggestionProvider; -import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.server.command.CommandHelper; -import org.spongepowered.api.command.CommandCause; -import org.spongepowered.api.event.CauseStackManager; -import org.spongepowered.api.event.EventContextKeys; -import org.spongepowered.api.service.permission.Subject; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.common.bridge.commands.CommandSourceStackBridge; -import org.spongepowered.common.command.manager.SpongeCommandManager; -import org.spongepowered.common.event.tracking.PhaseTracker; - -import java.util.IdentityHashMap; -import java.util.List; -import java.util.Map; -import java.util.WeakHashMap; -import java.util.function.Function; - -@Mixin(Commands.class) -public abstract class CommandsMixin_Forge { - - private WeakHashMap, List>>> impl$playerNodeCache; - private SpongeCommandManager impl$commandManager; - - // The event fired by Forge is fired in SpongeForgeCommandManager at the appropriate time. - @Redirect(method = "performCommand", - at = @At(value = "INVOKE", target = "Lnet/minecraftforge/eventbus/api/IEventBus;post(Lnet/minecraftforge/eventbus/api/Event;)Z")) - private boolean forge$redirectToSpongeCommandManager(IEventBus instance, Event event) { - return false; - } - - - @SuppressWarnings("unchecked") - @Redirect(method = "sendCommands", at = @At( - value = "INVOKE", - target = "Lnet/minecraftforge/server/command/CommandHelper;mergeCommandNode(Lcom/mojang/brigadier/tree/CommandNode;Lcom/mojang/brigadier/tree/CommandNode;Ljava/util/Map;Ljava/lang/Object;Lcom/mojang/brigadier/Command;Ljava/util/function/Function;)V", - remap = false - )) - private void impl$addNonBrigSuggestions( - final CommandNode sourceChild, - final CommandNode sourceNode, - final Map, CommandNode> resultNode, - final S sourceToResult, - final Command canUse, - final Function, SuggestionProvider> execute, - final ServerPlayer player - ) { - try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) { - frame.pushCause(player); - frame.addContext(EventContextKeys.SUBJECT, (Subject) player); - final CommandCause sourceToUse = ((CommandSourceStackBridge) sourceToResult).bridge$withCurrentCause(); - try { - this.impl$playerNodeCache.put(player, new IdentityHashMap<>()); - // We use this because the redirects should be a 1:1 mapping (which is what this map is for). - final IdentityHashMap, CommandNode> idMap = new IdentityHashMap<>(resultNode); - CommandHelper.mergeCommandNode(sourceChild, sourceNode, idMap, sourceToResult, canUse, execute); - } finally { - this.impl$playerNodeCache.remove(player); - } - for (final CommandNode node : this.impl$commandManager.getNonBrigadierSuggestions(sourceToUse)) { - sourceNode.addChild((CommandNode) node); - } - } - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/MinecraftForgeMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/MinecraftForgeMixin_Forge.java deleted file mode 100755 index 536ca09e693..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/MinecraftForgeMixin_Forge.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.minecraftforge; - -import net.neoforged.bus.BusBuilderImpl; -import net.neoforged.bus.api.BusBuilder; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.neoforge.common.NeoForge; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.forge.launch.event.ForgeEventManager; -import org.spongepowered.forge.launch.event.SpongeEventBus; - -@Mixin(NeoForge.class) -public abstract class MinecraftForgeMixin_Forge { - - @Redirect(method = "", at = @At(value = "INVOKE", - target = "Lnet/neoforged/bus/api/BusBuilder;build()Lnet/neoforged/bus/api/IEventBus;", remap = false)) - private static IEventBus forge$substituteForgeEventBus(final BusBuilder builder) { - return new ForgeEventManager(new SpongeEventBus((BusBuilderImpl) builder)); - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/EntityTravelToDimensionEventMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/EntityTravelToDimensionEventMixin_Forge.java deleted file mode 100755 index bb964ccbbfe..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/EntityTravelToDimensionEventMixin_Forge.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.minecraftforge.event.entity; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.level.Level; -import net.minecraftforge.event.entity.EntityEvent; -import net.minecraftforge.event.entity.EntityTravelToDimensionEvent; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.event.Event; -import org.spongepowered.api.event.SpongeEventFactory; -import org.spongepowered.api.event.entity.ChangeEntityWorldEvent; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.common.SpongeCommon; -import org.spongepowered.common.event.tracking.PhaseTracker; -import org.spongepowered.forge.launch.bridge.event.ForgeEventBridge_Forge; - -@Mixin(value = EntityTravelToDimensionEvent.class, remap = false) -public abstract class EntityTravelToDimensionEventMixin_Forge implements ForgeEventBridge_Forge { - - // @formatter:off - @Shadow @Final @Mutable private ResourceKey dimension; - // @formatter:on - - @Override - public void bridge$syncFrom(final Event event) { - if (event instanceof ChangeEntityWorldEvent.Pre) { - ((net.minecraftforge.eventbus.api.Event) (Object) this).setCanceled(((ChangeEntityWorldEvent.Pre) event).isCancelled()); - this.dimension = ((ServerLevel) ((ChangeEntityWorldEvent.Pre) event).destinationWorld()).dimension(); - } - } - - @Override - public void bridge$syncTo(final Event event) { - if (event instanceof ChangeEntityWorldEvent.Pre) { - ((ChangeEntityWorldEvent.Pre) event).setCancelled(((net.minecraftforge.eventbus.api.Event) (Object) this).isCanceled()); - } - } - - @Override - public @Nullable Event bridge$createSpongeEvent() { - final Entity entity = ((EntityEvent) (Object) this).getEntity(); - final ServerLevel toWorld = SpongeCommon.server().getLevel(this.dimension); - return SpongeEventFactory.createChangeEntityWorldEventPre(PhaseTracker.getCauseStackManager().currentCause(), - (org.spongepowered.api.entity.Entity) entity, (org.spongepowered.api.world.server.ServerWorld) entity.getCommandSenderWorld(), - (org.spongepowered.api.world.server.ServerWorld) toWorld, (org.spongepowered.api.world.server.ServerWorld) toWorld); - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/player/PlayerEvent_PlayerChangedDimensionEventMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/player/PlayerEvent_PlayerChangedDimensionEventMixin_Forge.java deleted file mode 100755 index f7490394fde..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/player/PlayerEvent_PlayerChangedDimensionEventMixin_Forge.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.minecraftforge.event.entity.player; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.level.Level; -import net.minecraftforge.event.entity.player.PlayerEvent; -import org.spongepowered.api.entity.Entity; -import org.spongepowered.api.event.Event; -import org.spongepowered.api.event.SpongeEventFactory; -import org.spongepowered.api.world.server.ServerWorld; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.common.SpongeCommon; -import org.spongepowered.common.event.tracking.PhaseTracker; -import org.spongepowered.forge.launch.bridge.event.ForgeEventBridge_Forge; - -@Mixin(value = PlayerEvent.PlayerChangedDimensionEvent.class, remap = false) -public final class PlayerEvent_PlayerChangedDimensionEventMixin_Forge implements ForgeEventBridge_Forge { - - // @formatter:off - @Shadow @Final private ResourceKey fromDim; - @Shadow @Final private ResourceKey toDim; - // @formatter:on - - @Override - public void bridge$syncFrom(final Event event) { - // nothing to do -- informational only - } - - @Override - public void bridge$syncTo(final Event event) { - // nothing to do -- informational only - } - - @SuppressWarnings("ConstantConditions") - @Override - public Event bridge$createSpongeEvent() { - final PlayerEvent.PlayerChangedDimensionEvent thisEvent = (PlayerEvent.PlayerChangedDimensionEvent) (Object) this; - return SpongeEventFactory.createChangeEntityWorldEventPost( - PhaseTracker.getCauseStackManager().currentCause(), - (Entity) thisEvent.getEntity(), - (ServerWorld) SpongeCommon.server().getLevel(this.fromDim), - (ServerWorld) SpongeCommon.server().getLevel(this.toDim), - (ServerWorld) SpongeCommon.server().getLevel(this.toDim) - ); - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEventMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEventMixin_Forge.java deleted file mode 100755 index 166b9201a39..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEventMixin_Forge.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.minecraftforge.event.world; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.event.level.BlockEvent; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(value = BlockEvent.class, remap = false) -public abstract class BlockEventMixin_Forge { - - // @formatter:off - @Shadow public abstract LevelAccessor shadow$getLevel(); - @Shadow public abstract BlockPos shadow$getPos(); - @Shadow public abstract BlockState shadow$getState(); - // @formatter:on - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEvent_BreakEventMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEvent_BreakEventMixin_Forge.java deleted file mode 100755 index 55845d3e685..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEvent_BreakEventMixin_Forge.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.minecraftforge.event.world; - -import net.minecraft.world.level.LevelAccessor; -import net.minecraftforge.event.level.BlockEvent; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.api.block.BlockState; -import org.spongepowered.api.block.BlockTypes; -import org.spongepowered.api.block.transaction.BlockTransaction; -import org.spongepowered.api.block.transaction.Operations; -import org.spongepowered.api.event.Event; -import org.spongepowered.api.event.SpongeEventFactory; -import org.spongepowered.api.event.block.ChangeBlockEvent; -import org.spongepowered.api.world.server.ServerWorld; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.common.block.SpongeBlockSnapshot; -import org.spongepowered.common.event.tracking.PhaseTracker; -import org.spongepowered.common.util.VecHelper; -import org.spongepowered.forge.launch.bridge.event.ForgeEventBridge_Forge; -import org.spongepowered.math.vector.Vector3i; - -import java.util.Collections; - -@Mixin(value = BlockEvent.BreakEvent.class, remap = false) -public abstract class BlockEvent_BreakEventMixin_Forge extends BlockEventMixin_Forge implements ForgeEventBridge_Forge { - - @Override - public void bridge$syncFrom(final Event event) { - if (event instanceof ChangeBlockEvent.All) { - final ChangeBlockEvent.All changeBlockEventAll = (ChangeBlockEvent.All) event; - final Vector3i pos = VecHelper.toVector3i(this.shadow$getPos()); - if (changeBlockEventAll.isCancelled() || - changeBlockEventAll.transactions() - .stream() - .filter(x -> x.original().position().equals(pos)) - .anyMatch(x -> !x.isValid() || x.operation() != Operations.BREAK.get() || x.custom().isPresent())) { - ((net.minecraftforge.eventbus.api.Event) (Object) this).setCanceled(true); - } - } - } - - @Override - public void bridge$syncTo(final Event event) { - if (event instanceof ChangeBlockEvent.All && ((net.minecraftforge.eventbus.api.Event) (Object) this).isCanceled()) { - final Vector3i pos = VecHelper.toVector3i(this.shadow$getPos()); - ((ChangeBlockEvent.All) event).transactions(Operations.BREAK.get()).filter(x -> x.original().position().equals(pos)) - .forEach(x -> x.setValid(false)); - } - } - - @Override - public @Nullable Event bridge$createSpongeEvent() { - final LevelAccessor accessor = this.shadow$getLevel(); - if (accessor instanceof ServerWorld) { - final ServerWorld serverWorld = (ServerWorld) accessor; - final BlockTransaction transaction = new BlockTransaction( - SpongeBlockSnapshot.BuilderImpl - .pooled() - .world(serverWorld.key()) - .position(VecHelper.toVector3i(this.shadow$getPos())) - .blockState((BlockState) this.shadow$getState()) - .build(), - SpongeBlockSnapshot.BuilderImpl - .pooled() - .world(serverWorld.key()) - .position(VecHelper.toVector3i(this.shadow$getPos())) - .blockState(BlockState.builder().blockType(BlockTypes.AIR.get()).build()) - .build(), - Operations.BREAK.get() - ); - return SpongeEventFactory.createChangeBlockEventAll(PhaseTracker.getCauseStackManager().currentCause(), - Collections.singletonList(transaction), serverWorld); - } - return null; - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/internal/BrandingControlMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/internal/BrandingControlMixin_Forge.java deleted file mode 100755 index 841f6ba78ea..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/internal/BrandingControlMixin_Forge.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.minecraftforge.internal; - -import net.minecraftforge.internal.BrandingControl; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; - -@Mixin(value = BrandingControl.class, remap = false) -public abstract class BrandingControlMixin_Forge { - - /** - * @author Zidane - * @reason This is also not Kansas anymore - */ - @Overwrite - public static String getClientBranding() { - return "forge/spongeforge"; - } - - /** - * @author Zidane - * @reason What that said above - */ - @Overwrite - public static String getServerBranding() { - return "forge/spongeforge"; - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/ForgeRegistryMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/ForgeRegistryMixin_Forge.java deleted file mode 100755 index d382d4bd688..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/ForgeRegistryMixin_Forge.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.minecraftforge.registries; - -import com.google.common.collect.Maps; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.registries.ForgeRegistry; -import net.minecraftforge.registries.IForgeRegistry; -import org.spongepowered.api.ResourceKey; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.common.SpongeCommon; -import org.spongepowered.common.bridge.core.RegistryBridge; -import org.spongepowered.common.registry.SpongeRegistryEntry; -import org.spongepowered.common.registry.SpongeRegistryType; - -import java.util.Map; -import java.util.StringJoiner; - -@Mixin(ForgeRegistry.class) -public abstract class ForgeRegistryMixin_Forge { - - // @formatter:off - @Shadow @Final private net.minecraft.resources.ResourceKey> key; - // @formatter:on - - private final Map> forge$parents = Maps.newHashMap(); - private boolean forge$warnedIfNoParent; - - @Inject(method = "add(ILnet/minecraft/resources/ResourceLocation;Ljava/lang/Object;Ljava/lang/String;)I", at = @At("TAIL")) - public void forge$writeToParent(final int id, final ResourceLocation key, final V value, final String owner, final CallbackInfoReturnable cir) { - final ResourceKey root = (ResourceKey) (Object) this.key.registry(); - final ResourceKey location = (ResourceKey) (Object) this.key.location(); - - if (!this.forge$warnedIfNoParent && this.forge$parents.isEmpty()) { - // We only care about minecraft namespaced registries, as that is what we've got parents for. - if (location.namespace().equalsIgnoreCase("minecraft")) { - SpongeCommon.logger().error(String.format( - "No parent registry found for %s, things might not work correctly!", - new StringJoiner("/").add(root.formatted()).add(location.formatted()) - )); - } - this.forge$warnedIfNoParent = true; - } - - final SpongeRegistryEntry entry = new SpongeRegistryEntry<>(new SpongeRegistryType<>(root, location), - (ResourceKey) (Object) key, value); - - this.forge$parents.values().forEach(registry -> registry.bridge$register(entry)); - } - - @SuppressWarnings("unchecked") - @Inject(method = "setSlaveMap", at = @At("TAIL")) - public void forge$establishParent(final IForgeRegistry.SlaveKey key, final Object obj, final CallbackInfo ci) { - if (obj instanceof RegistryBridge) { - this.forge$parents.put((ResourceKey) (Object) key.name(), (RegistryBridge) obj); - } - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/RegistryManagerMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/RegistryManagerMixin_Forge.java deleted file mode 100755 index f591b0f1463..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/RegistryManagerMixin_Forge.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.minecraftforge.registries; - -import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.registries.ForgeRegistry; -import net.minecraftforge.registries.RegistryManager; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.Map; - -@Mixin(RegistryManager.class) -public class RegistryManagerMixin_Forge { - - @SuppressWarnings("UnstableApiUsage") - @Inject(method = "takeSnapshot", at = @At("RETURN")) - public void forge$dontSendSpongeDataToClient(boolean savingToDisc, CallbackInfoReturnable> cir) { - if (savingToDisc) { - return; - } - - for (ForgeRegistry.Snapshot snapshot : cir.getReturnValue().values()) { - snapshot.ids.keySet().removeIf(loc -> loc.getNamespace().equals("sponge")); - } - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/network/ConnectionMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/network/ConnectionMixin_Forge.java deleted file mode 100755 index ed066933318..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/network/ConnectionMixin_Forge.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.network; - -import io.netty.util.concurrent.Future; -import net.minecraft.network.Connection; -import net.minecraft.network.PacketSendListener; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.common.network.channel.PacketSender; - -@Mixin(Connection.class) -public abstract class ConnectionMixin_Forge { - - @Inject(method = "lambda$doSendPacket$15", at = @At(value = "INVOKE", target = "Lio/netty/util/concurrent/Future;isSuccess()Z")) - public void impl$onPacketSent(final PacketSendListener listener, final Future future, final CallbackInfo ci) { - if (listener instanceof final PacketSender.SpongePacketSendListener spongeListener) { - spongeListener.accept(future.cause()); - } - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/BootstrapMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/BootstrapMixin_Forge.java deleted file mode 100755 index d999fb6f0e9..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/BootstrapMixin_Forge.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.server; - -import com.google.inject.Injector; -import com.google.inject.Stage; -import net.minecraft.server.Bootstrap; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.common.SpongeCommon; -import org.spongepowered.common.SpongeLifecycle; -import org.spongepowered.common.inject.SpongeGuice; -import org.spongepowered.common.launch.Launch; -import org.spongepowered.forge.launch.ForgeLaunch; - -@Mixin(Bootstrap.class) -public abstract class BootstrapMixin_Forge { - - // @formatter:off - @Shadow private static boolean isBootstrapped; - // @formatter:on - - @Inject(method = "bootStrap", at = @At("HEAD")) - private static void forge$startLifecycle(final CallbackInfo ci) { - if (BootstrapMixin_Forge.isBootstrapped) { - return; - } - final ForgeLaunch launch = Launch.instance(); - final Stage stage = SpongeGuice.getInjectorStage(launch.injectionStage()); - SpongeCommon.logger().debug("Creating injector in stage '{}'", stage); - final Injector bootstrapInjector = launch.createInjector(); - final SpongeLifecycle lifecycle = bootstrapInjector.getInstance(SpongeLifecycle.class); - launch.setLifecycle(lifecycle); - lifecycle.establishFactories(); - lifecycle.establishBuilders(); - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MainMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MainMixin_Forge.java deleted file mode 100755 index 46b233af9ee..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MainMixin_Forge.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.server; - -import net.minecraft.server.Main; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.common.applaunch.AppLaunch; -import org.spongepowered.common.applaunch.plugin.PluginPlatform; -import org.spongepowered.common.launch.Launch; -import org.spongepowered.forge.launch.ForgeLaunch; - -@Mixin(Main.class) -public abstract class MainMixin_Forge { - - @Inject(method = "", at = @At("RETURN")) - private static void forge$initLaunch(final CallbackInfo ci) { - final PluginPlatform pluginPlatform = AppLaunch.pluginPlatform(); - final ForgeLaunch launch = new ForgeLaunch(pluginPlatform); - Launch.setInstance(launch); - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MinecraftServerMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MinecraftServerMixin_Forge.java deleted file mode 100755 index d64d8c83bd5..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/MinecraftServerMixin_Forge.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.server; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.Level; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.common.bridge.server.level.ServerLevelBridge; -import org.spongepowered.forge.ForgeServer; - -@Mixin(MinecraftServer.class) -public abstract class MinecraftServerMixin_Forge implements ForgeServer { - - // @formatter:off - @Shadow @Nullable public abstract ServerLevel shadow$getLevel(ResourceKey p_71218_1_); - // @formatter:on - - /** - * @author Zidane - * @reason We store the per-world tick time on the ServerLevel itself to more accurately track this. - */ - @Overwrite(remap = false) - public long[] getTickTime(ResourceKey dim) { - return ((ServerLevelBridge) this.shadow$getLevel(dim)).bridge$recentTickTimes(); - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/commands/SpreadPlayersCommandMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/commands/SpreadPlayersCommandMixin_Forge.java deleted file mode 100755 index 94adf0c914b..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/commands/SpreadPlayersCommandMixin_Forge.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.server.commands; - -import net.minecraft.server.commands.SpreadPlayersCommand; -import net.minecraft.world.entity.Entity; -import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.event.entity.EntityTeleportEvent; -import org.spongepowered.api.event.CauseStackManager; -import org.spongepowered.api.event.EventContextKeys; -import org.spongepowered.api.event.cause.entity.MovementTypes; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.common.event.tracking.PhaseTracker; - -@Mixin(SpreadPlayersCommand.class) -public abstract class SpreadPlayersCommandMixin_Forge { - - @Redirect(method = "setPlayerPositions", at = @At( - value = "INVOKE", - target = "Lnet/minecraftforge/event/ForgeEventFactory;onEntityTeleportSpreadPlayersCommand(Lnet/minecraft/world/entity/Entity;DDD)Lnet/minecraftforge/event/entity/EntityTeleportEvent$SpreadPlayersCommand;" - )) - private static EntityTeleportEvent.SpreadPlayersCommand vanilla$createCauseFrameForTeleport(Entity entity, double targetX, double targetY, double targetZ) { - try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) { - frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND); - - return ForgeEventFactory.onEntityTeleportSpreadPlayersCommand(entity, targetX, targetY, targetZ); - } - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/level/ServerPlayerMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/level/ServerPlayerMixin_Forge.java deleted file mode 100755 index b06f9cb2cce..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/level/ServerPlayerMixin_Forge.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.server.level; - -import net.minecraft.server.level.ServerPlayer; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.common.event.tracking.PhaseContext; -import org.spongepowered.common.event.tracking.PhaseTracker; -import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor; -import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier; -import org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction; -import org.spongepowered.forge.mixin.core.world.entity.LivingEntityMixin_Forge; - -@Mixin(ServerPlayer.class) -public abstract class ServerPlayerMixin_Forge extends LivingEntityMixin_Forge { - - // override from LivingEntityMixin_Forge - @Override - protected void forge$onElytraUse(final CallbackInfo ci) { - final PhaseContext context = PhaseTracker.SERVER.getPhaseContext(); - final TransactionalCaptureSupplier transactor = context.getTransactor(); - final net.minecraft.server.level.ServerPlayer player = (net.minecraft.server.level.ServerPlayer) (Object) this; - try (final EffectTransactor ignored = transactor.logPlayerInventoryChangeWithEffect(player, PlayerInventoryTransaction.EventCreator.STANDARD)) { - player.inventoryMenu.broadcastChanges(); // capture - } - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerGamePacketListenerImplMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerGamePacketListenerImplMixin_Forge.java deleted file mode 100755 index f8e9a9a30af..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerGamePacketListenerImplMixin_Forge.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.server.network; - -import net.minecraft.network.protocol.game.ServerGamePacketListener; -import net.minecraft.server.network.ServerGamePacketListenerImpl; -import net.minecraft.world.inventory.RecipeBookMenu; -import net.minecraft.world.item.crafting.RecipeHolder; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.item.inventory.Inventory; -import org.spongepowered.api.item.inventory.crafting.CraftingInventory; -import org.spongepowered.api.item.inventory.query.QueryTypes; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.common.SpongeCommon; -import org.spongepowered.common.event.tracking.PhaseContext; -import org.spongepowered.common.event.tracking.PhaseTracker; -import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor; -import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier; - -@Mixin(ServerGamePacketListenerImpl.class) -public abstract class ServerGamePacketListenerImplMixin_Forge implements ServerGamePacketListener { - - @SuppressWarnings({"unchecked", "rawtypes"}) - @Redirect(method = "lambda$handlePlaceRecipe$10", - at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/RecipeBookMenu;handlePlacement(ZLnet/minecraft/world/item/crafting/RecipeHolder;Lnet/minecraft/server/level/ServerPlayer;)V")) - private void forge$onPlaceRecipe(final RecipeBookMenu recipeBookMenu, final boolean shift, final RecipeHolder recipe, final net.minecraft.server.level.ServerPlayer player) { - final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext(); - final TransactionalCaptureSupplier transactor = context.getTransactor(); - - final Inventory craftInv = ((Inventory) player.containerMenu).query(QueryTypes.INVENTORY_TYPE.get().of(CraftingInventory.class)); - if (!(craftInv instanceof CraftingInventory)) { - recipeBookMenu.handlePlacement(shift, recipe, player); - SpongeCommon.logger().warn("Detected crafting without a InventoryCrafting!? Crafting Event will not fire."); - return; - } - - try (final EffectTransactor ignored = transactor.logPlaceRecipe(shift, recipe, player, (CraftingInventory) craftInv)) { - recipeBookMenu.handlePlacement(shift, recipe, player); - player.containerMenu.broadcastChanges(); - } - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerLoginPacketListenerImplMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerLoginPacketListenerImplMixin_Forge.java deleted file mode 100755 index 38fdc9aaff5..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/server/network/ServerLoginPacketListenerImplMixin_Forge.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.server.network; - -import net.minecraft.network.protocol.login.ServerLoginPacketListener; -import net.minecraft.server.network.ServerLoginPacketListenerImpl; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.common.bridge.network.ServerLoginPacketListenerImplBridge; - -@Mixin(ServerLoginPacketListenerImpl.class) -public abstract class ServerLoginPacketListenerImplMixin_Forge implements ServerLoginPacketListener, ServerLoginPacketListenerImplBridge { - - // @formatter:off - @Shadow private ServerLoginPacketListenerImpl.State state; - // @formatter:on - - @Inject(method = "tick", at = @At("HEAD")) - private void impl$onTick(final CallbackInfo ci) { - // In SpongeVanilla we do channel registration during this state, not sure if we need to do anything in SpongeForge - if (this.state == ServerLoginPacketListenerImpl.State.NEGOTIATING) { - this.state = ServerLoginPacketListenerImpl.State.VERIFYING; - } - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge.java deleted file mode 100755 index 819262550c7..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.world.entity; - -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.LivingEntity; -import net.minecraftforge.common.ForgeHooks; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.common.bridge.world.entity.PlatformLivingEntityBridge; - -@Mixin(value = LivingEntity.class) -public abstract class LivingEntityMixin_Forge implements PlatformLivingEntityBridge { - - @Inject( - method = "updateFallFlying", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/item/ItemStack;elytraFlightTick(Lnet/minecraft/world/entity/LivingEntity;I)Z", - shift = At.Shift.AFTER - ) - ) - protected void forge$onElytraUse(final CallbackInfo ci) { - } - - @Override - public boolean bridge$onLivingAttack(final LivingEntity entity, final DamageSource source, final float amount) { - return ForgeHooks.onLivingAttack(entity, source, amount); - } - - @Override - public float bridge$applyModDamage(final LivingEntity entity, final DamageSource source, final float damage) { - return ForgeHooks.onLivingHurt(entity, source, damage); - } - - @Override - public float bridge$applyModDamageBeforeFunctions(final LivingEntity entity, final DamageSource source, final float damage) { - return ForgeHooks.onLivingDamage(entity, source, damage); - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge_Attack_Impl.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge_Attack_Impl.java deleted file mode 100755 index 1cb83895595..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge_Attack_Impl.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.world.entity; - -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.stats.Stat; -import net.minecraft.world.entity.LivingEntity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(LivingEntity.class) -public class LivingEntityMixin_Forge_Attack_Impl { - - /** - * Prevents {@link ServerPlayer#awardStat} from running before event - */ - @Redirect(method = "getDamageAfterMagicAbsorb", - at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;awardStat(Lnet/minecraft/stats/Stat;I)V")) - public void attackImpl$onAwardStatDamageResist(final ServerPlayer instance, final Stat resourceLocation, final int i) { - // do nothing - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/item/ItemEntityMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/item/ItemEntityMixin_Forge.java deleted file mode 100755 index 1ad9b4ed978..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/item/ItemEntityMixin_Forge.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.world.entity.item; - -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.level.Level; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.common.config.SpongeGameConfigs; - -@Mixin(ItemEntity.class) -public abstract class ItemEntityMixin_Forge { - - // @formatter:off - @Shadow public int lifespan; - // @formatter:on - - @Inject(method = "(Lnet/minecraft/world/entity/EntityType;Lnet/minecraft/world/level/Level;)V", at = @At("RETURN")) - private void forge$setLifespanFromConfig(final EntityType type, final Level level, - final CallbackInfo ci - ) { - // Check the level is not null to avoid an NPE - if (level != null && !level.isClientSide) { - this.lifespan = SpongeGameConfigs.getForWorld(level).get().entity.item.despawnRate; - } - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/player/PlayerMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/player/PlayerMixin_Forge.java deleted file mode 100755 index e49f36b530a..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/player/PlayerMixin_Forge.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.world.entity.player; - -import net.minecraft.world.damagesource.DamageSource; -import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.player.Player; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.forge.mixin.core.world.entity.LivingEntityMixin_Forge; - -@Mixin(Player.class) -public class PlayerMixin_Forge extends LivingEntityMixin_Forge { - @Override - public boolean bridge$onLivingAttack( - final LivingEntity entity, final DamageSource source, final float amount - ) { - return true; - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/projectile/ThrownEnderpealMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/projectile/ThrownEnderpealMixin_Forge.java deleted file mode 100755 index ef47ed235d9..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/projectile/ThrownEnderpealMixin_Forge.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.world.entity.projectile; - -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.projectile.ThrownEnderpearl; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(ThrownEnderpearl.class) -public abstract class ThrownEnderpealMixin_Forge { - - @Redirect(method = "changeDimension", - at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/projectile/ThrownEnderpearl;getOwner()Lnet/minecraft/world/entity/Entity;")) - private Entity forge$preventUnsetOwnerUntilLater(final ThrownEnderpearl thrownEnderpearl) { - // This allows us to ensure the if statement after is always false - // We deal with this later (see the common mixin) - return null; - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/vehicle/BoatMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/vehicle/BoatMixin_Forge.java deleted file mode 100755 index f00eb8a1c45..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/vehicle/BoatMixin_Forge.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.world.entity.vehicle; - -import net.minecraft.core.BlockPos; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.vehicle.Boat; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.common.bridge.world.entity.vehicle.BoatBridge; - -@Mixin(Boat.class) -public abstract class BoatMixin_Forge implements BoatBridge { - - @Redirect(method = "getGroundFriction", at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/level/block/state/BlockState;getFriction(Lnet/minecraft/world/level/LevelReader;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/Entity;)F") - ) - private float forge$getBlockFrictionIfBoatIsNotOverridingMovingOnLand(BlockState caller, LevelReader level, BlockPos pos, Entity entity) { - final boolean movesOnLand = this.bridge$getMoveOnLand(); - final float friction = caller.getFriction(level, pos, entity); - if (movesOnLand && friction == 0.6f) { - return Blocks.ICE.getFriction(caller, level, pos, entity); - } - return friction; - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/FireBlockMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/FireBlockMixin_Forge.java deleted file mode 100755 index da13efce569..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/FireBlockMixin_Forge.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.world.level.block; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.FireBlock; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.common.bridge.server.level.ServerLevelBridge; -import org.spongepowered.common.event.ShouldFire; -import org.spongepowered.common.event.SpongeCommonEventFactory; - -@Mixin(FireBlock.class) -public class FireBlockMixin_Forge { - // forge changes the signature of this method - @Inject(method = "checkBurnOut", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/level/Level;setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;I)Z"), - require = 0, - expect = 0, - cancellable = true) - private void impl$onCatchFirePreCheck( - final Level world, final BlockPos pos, final int chance, final RandomSource random, final int age, final Direction dir, final CallbackInfo callbackInfo) { - if (!world.isClientSide) { - if (ShouldFire.CHANGE_BLOCK_EVENT_PRE && SpongeCommonEventFactory.callChangeBlockEventPre((ServerLevelBridge) world, pos).isCancelled()) { - callbackInfo.cancel(); - } - } - } - - @Inject(method = "checkBurnOut", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/level/Level;removeBlock(Lnet/minecraft/core/BlockPos;Z)Z"), - require = 0, - expect = 0, - cancellable = true) - private void impl$onCatchFirePreCheckOther( - final Level world, final BlockPos pos, final int chance, final RandomSource random, final int age, final Direction dir, final CallbackInfo callbackInfo) { - if (!world.isClientSide) { - if (ShouldFire.CHANGE_BLOCK_EVENT_PRE && SpongeCommonEventFactory.callChangeBlockEventPre((ServerLevelBridge) world, pos).isCancelled()) { - callbackInfo.cancel(); - } - } - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin_Forge.java deleted file mode 100755 index fa068009ebe..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin_Forge.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.core.world.level.block.entity; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.NonNullList; -import net.minecraft.core.RegistryAccess; -import net.minecraft.util.Mth; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.RecipeHolder; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import org.objectweb.asm.Opcodes; -import org.spongepowered.api.ResourceKey; -import org.spongepowered.api.block.entity.carrier.furnace.FurnaceBlockEntity; -import org.spongepowered.api.event.Cause; -import org.spongepowered.api.event.SpongeEventFactory; -import org.spongepowered.api.event.block.entity.CookingEvent; -import org.spongepowered.api.item.inventory.ItemStackSnapshot; -import org.spongepowered.api.item.inventory.transaction.SlotTransaction; -import org.spongepowered.api.item.recipe.cooking.CookingRecipe; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.Slice; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import org.spongepowered.common.MixinTargetHelper; -import org.spongepowered.common.SpongeCommon; -import org.spongepowered.common.bridge.block.entity.AbstractFurnaceBlockEntityBridge; -import org.spongepowered.common.event.tracking.PhaseTracker; -import org.spongepowered.common.inventory.adapter.impl.slots.SlotAdapter; -import org.spongepowered.common.item.util.ItemStackUtil; - -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -@Mixin(AbstractFurnaceBlockEntity.class) -public abstract class AbstractFurnaceBlockEntityMixin_Forge implements AbstractFurnaceBlockEntityBridge { - - // @formatter:off - @Shadow protected NonNullList items; - @Shadow int cookingProgress; - @Shadow private boolean shadow$canBurn(RegistryAccess registryAccess, @Nullable RecipeHolder recipe, NonNullList slots, int maxStackSize) { - throw new IllegalStateException("Mixin failed to shadow canBurn"); - } - // @formatter:on - - private boolean forgeImpl$filledWaterBucket; - - // Tick up and Start - @Redirect(method = "serverTick", - at = @At(value = "INVOKE", - target = "Lnet/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity;canBurn(Lnet/minecraft/core/RegistryAccess;Lnet/minecraft/world/item/crafting/RecipeHolder;Lnet/minecraft/core/NonNullList;I)Z", - ordinal = 1)) - private static boolean forgeImpl$checkIfCanSmelt(final AbstractFurnaceBlockEntity entity, - final RegistryAccess registryAccess, - final RecipeHolder recipe, - final NonNullList slots, - final int maxStackSize) { - final var $this = (AbstractFurnaceBlockEntityMixin_Forge) (Object) (entity); - if (!$this.shadow$canBurn(registryAccess, recipe, slots, maxStackSize)) { - return false; - } - - final ItemStackSnapshot fuel = ItemStackUtil.snapshotOf(slots.get(1)); - - final Cause cause = PhaseTracker.getCauseStackManager().currentCause(); - if ($this.cookingProgress == 0) { // Start - final CookingEvent.Start event = SpongeEventFactory.createCookingEventStart(cause, (FurnaceBlockEntity) entity, Optional.of(fuel), - Optional.of((CookingRecipe) recipe.value()), Optional.of((ResourceKey) (Object) recipe.id())); - SpongeCommon.post(event); - return !event.isCancelled(); - } else { // Tick up - final ItemStackSnapshot cooking = ItemStackUtil.snapshotOf($this.items.get(0)); - final CookingEvent.Tick event = SpongeEventFactory.createCookingEventTick(cause, (FurnaceBlockEntity) entity, cooking, Optional.of(fuel), - Optional.of((CookingRecipe) recipe.value()), Optional.of((ResourceKey) (Object) recipe.id())); - SpongeCommon.post(event); - return !event.isCancelled(); - } - } - - // Tick down - @Redirect(method = "serverTick", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Mth;clamp(III)I")) - private static int forgeImpl$resetCookTimeIfCancelled(final int newCookTime, final int zero, final int totalCookTime, - final Level level, final BlockPos entityPos, final BlockState state, final AbstractFurnaceBlockEntity entity) { - final int clampedCookTime = Mth.clamp(newCookTime, zero, totalCookTime); - final var thisEntity = (AbstractFurnaceBlockEntityMixin_Forge) (Object) entity; - final ItemStackSnapshot fuel = ItemStackUtil.snapshotOf(thisEntity.items.get(1)); - final Cause cause = PhaseTracker.getCauseStackManager().currentCause(); - final var recipe = thisEntity.bridge$getCurrentRecipe(); - final ItemStackSnapshot cooking = ItemStackUtil.snapshotOf(thisEntity.items.get(0)); - final CookingEvent.Tick event = SpongeEventFactory.createCookingEventTick(cause, (FurnaceBlockEntity) entity, cooking, Optional.of(fuel), - recipe.map(r -> (CookingRecipe) r.value()), recipe.map(r -> (ResourceKey) (Object) r.id())); - SpongeCommon.post(event); - if (event.isCancelled()) { - return thisEntity.cookingProgress; // dont tick down - } - - return clampedCookTime; - } - - // Finish - @Inject(method = "burn", at = @At(value = "INVOKE", target = "Lnet/minecraft/core/NonNullList;set(ILjava/lang/Object;)Ljava/lang/Object;"), - slice = @Slice( - from = @At(value = "FIELD", target = "Lnet/minecraft/world/level/block/Blocks;WET_SPONGE:Lnet/minecraft/world/level/block/Block;", opcode = Opcodes.GETSTATIC) - )) - private void forgeImpl$captureBucketFill(final RegistryAccess $$0, final RecipeHolder $$1, final NonNullList $$2, final int $$3, final CallbackInfoReturnable cir) { - final AbstractFurnaceBlockEntityMixin_Forge mixinSelf = MixinTargetHelper.cast(this); - mixinSelf.forgeImpl$filledWaterBucket = true; - } - - @Inject( - method = "burn", - locals = LocalCapture.CAPTURE_FAILHARD, - at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;shrink(I)V")) - private void forgeImpl$afterSmeltItem( - final RegistryAccess registryAccess, final RecipeHolder recipe, - final NonNullList slots, final int var2, - final CallbackInfoReturnable cir, - final ItemStack $$4, final ItemStack $$5, final ItemStack $$6 - ) { - final AbstractFurnaceBlockEntityMixin_Forge mixinSelf = MixinTargetHelper.cast(this); - final FurnaceBlockEntity entity = (FurnaceBlockEntity) this; - - final List transactions = new ArrayList<>(); - $$4.grow(1); - final ItemStackSnapshot originalSmeltItem = ItemStackUtil.snapshotOf($$4); - $$4.shrink(1); - transactions.add(new SlotTransaction(entity.inventory().slot(0).get(), originalSmeltItem, ItemStackUtil.snapshotOf($$4))); - - final boolean hasFuel = !mixinSelf.forgeImpl$filledWaterBucket; - if (mixinSelf.forgeImpl$filledWaterBucket) { - transactions.add(new SlotTransaction(entity.inventory().slot(1).get(), ItemStackSnapshot.empty(), ItemStackUtil.snapshotOf(slots.get(1)))); - } - mixinSelf.forgeImpl$filledWaterBucket = false; - - if ($$6.isEmpty()) { - transactions.add(new SlotTransaction(entity.inventory().slot(2).get(), ItemStackSnapshot.empty(), ItemStackUtil.snapshotOf($$5))); - } else if (ItemStack.isSameItemSameComponents($$6, $$5)) { - $$6.shrink(1); - final ItemStackSnapshot originalResult = ItemStackUtil.snapshotOf($$6); - $$6.grow(1); - transactions.add(new SlotTransaction(entity.inventory().slot(2).get(), originalResult, ItemStackUtil.snapshotOf($$6))); - } - final Optional fuel = hasFuel && !slots.get(1).isEmpty() ? Optional.of(ItemStackUtil.snapshotOf(slots.get(1))) : Optional.empty(); - final CookingEvent.Finish event = SpongeEventFactory.createCookingEventFinish(PhaseTracker.getCauseStackManager().currentCause(), entity, - fuel, Optional.ofNullable((CookingRecipe) recipe.value()), Optional.of((ResourceKey) (Object) recipe.id()), Collections.unmodifiableList(transactions)); - SpongeCommon.post(event); - - for (final SlotTransaction transaction : transactions) { - transaction.custom().ifPresent(item -> slots.set(((SlotAdapter) transaction.slot()).getOrdinal(), ItemStackUtil.fromSnapshotToNative(item))); - } - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/package-info.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/package-info.java deleted file mode 100755 index 959126e7358..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/package-info.java +++ /dev/null @@ -1,6 +0,0 @@ - -@DefaultQualifier(NonNull.class) -package org.spongepowered.forge.mixin.core.world.level.block.entity; - -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.framework.qual.DefaultQualifier; diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/inventory/event/world/level/block/entity/HopperBlockEntityMixin_Inventory_Forge.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/inventory/event/world/level/block/entity/HopperBlockEntityMixin_Inventory_Forge.java deleted file mode 100755 index da26926ab18..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/inventory/event/world/level/block/entity/HopperBlockEntityMixin_Inventory_Forge.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.inventory.event.world.level.block.entity; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.Container; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.HopperBlockEntity; -import org.spongepowered.api.item.inventory.Inventory; -import org.spongepowered.api.item.inventory.transaction.SlotTransaction; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import org.spongepowered.common.accessor.world.level.block.entity.HopperBlockEntityAccessor; -import org.spongepowered.common.bridge.world.inventory.container.TrackedInventoryBridge; -import org.spongepowered.common.event.ShouldFire; -import org.spongepowered.common.event.inventory.InventoryEventFactory; -import org.spongepowered.common.inventory.util.InventoryUtil; - -@Mixin(HopperBlockEntity.class) -public abstract class HopperBlockEntityMixin_Inventory_Forge { - - @Redirect(method = "ejectItems", - at = @At(value = "INVOKE", - target = "Lnet/minecraft/world/level/block/entity/HopperBlockEntity;isFullContainer(Lnet/minecraft/world/Container;Lnet/minecraft/core/Direction;)Z")) - private static boolean forge$throwTransferPreIfNotFull( - final Container attachedContainer, final Direction direction, final Level level, final BlockPos pos, final HopperBlockEntity block - ) { - final boolean result = HopperBlockEntityAccessor.invoker$isFullContainer(attachedContainer, direction); - if (result || !ShouldFire.TRANSFER_INVENTORY_EVENT_PRE) { - return result; - } - return InventoryEventFactory.callTransferPre(InventoryUtil.toInventory(block), InventoryUtil.toInventory(attachedContainer)).isCancelled(); - } - -// Post Captured Transactions - - @Inject(method = "ejectItems", locals = LocalCapture.CAPTURE_FAILHARD, - at = @At(value = "INVOKE", - target = "Lnet/minecraft/world/item/ItemStack;isEmpty()Z", - ordinal = 1)) - private static void forge$afterPutStackInSlots( - final Level var0, final BlockPos var1, final HopperBlockEntity var3, - final CallbackInfoReturnable cir, final Container iInventory, final Direction enumFacing, - final int i, final ItemStack itemStack, final int count,final ItemStack itemStack1 - ) { - // after putStackInInventoryAllSlots if the transfer worked - if (ShouldFire.TRANSFER_INVENTORY_EVENT_POST && itemStack1.isEmpty()) { - // Capture Insert in Origin - final TrackedInventoryBridge capture = InventoryUtil.forCapture(var3); - final SlotTransaction sourceSlotTransaction = InventoryEventFactory.captureTransaction(capture, (Inventory) var3, i, itemStack); - // Call event - InventoryEventFactory.callTransferPost(capture, (Inventory) iInventory, InventoryUtil.toInventory(iInventory), itemStack, sourceSlotTransaction); - } - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/plugin/ForgeCorePlugin.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/plugin/ForgeCorePlugin.java deleted file mode 100755 index 88d71961e72..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/plugin/ForgeCorePlugin.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.plugin; - -import cpw.mods.modlauncher.Environment; -import cpw.mods.modlauncher.Launcher; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.spongepowered.common.mixin.plugin.AbstractMixinConfigPlugin; - -import java.lang.reflect.InvocationTargetException; - -// just a way to get on the TCL nice and early -public class ForgeCorePlugin extends AbstractMixinConfigPlugin { - - private static final Logger LOGGER = LogManager.getLogger(); - - public ForgeCorePlugin() { - // todo: too tired for gradle - try { - Class.forName("org.spongepowered.forge.applaunch.plugin.ForgePluginPlatform") - .getMethod("bootstrap", Environment.class) - .invoke(null, Launcher.INSTANCE.environment()); - } catch (final ClassNotFoundException | InvocationTargetException | IllegalAccessException | NoSuchMethodException ex) { - ForgeCorePlugin.LOGGER.error("Failed to bootstrap the Forge plugin platform on TCL", ex); - } - } - -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/server/level/ServerPlayerGameModeMixin_Forge_Tracker.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/server/level/ServerPlayerGameModeMixin_Forge_Tracker.java deleted file mode 100755 index b3f8c60f891..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/server/level/ServerPlayerGameModeMixin_Forge_Tracker.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.tracker.server.level; - -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.level.ServerPlayerGameMode; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.common.event.tracking.PhaseContext; -import org.spongepowered.common.event.tracking.PhaseTracker; -import org.spongepowered.common.event.tracking.context.transaction.EffectTransactor; -import org.spongepowered.common.event.tracking.context.transaction.ResultingTransactionBySideEffect; -import org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier; -import org.spongepowered.common.event.tracking.context.transaction.effect.InventoryEffect; -import org.spongepowered.common.event.tracking.context.transaction.inventory.PlayerInventoryTransaction; - -@Mixin(ServerPlayerGameMode.class) -public abstract class ServerPlayerGameModeMixin_Forge_Tracker { - - // @formatter:off - @Shadow @Final protected ServerPlayer player; - // @formatter:on - - @Redirect( - method = "destroyBlock", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/item/ItemStack;mineBlock(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/player/Player;)V" - ) - ) - private void forgeTracker$pushTransactionAndEffect( - final ItemStack itemStack, final Level level, final BlockState state, final BlockPos pos, - final Player player - ) { - final PhaseContext<@NonNull ?> context = PhaseTracker.SERVER.getPhaseContext(); - final TransactionalCaptureSupplier transactor = context.getTransactor(); - // Log the prepare drops here because Forge rewrites - // this method to call mine block before calling destroy block - // and mods will possibly already have performed modifications on - // the block before we can capture it in level.destroy. - transactor.logBlockDrops(level, pos, state, level.getBlockEntity(pos)); - - itemStack.mineBlock(level, state, pos, player); - // Needs to get logged as a sideeffect under the BlockChange - try (EffectTransactor ignored = context.getTransactor().pushEffect(new ResultingTransactionBySideEffect( - InventoryEffect.getInstance()))) { - transactor.logPlayerInventoryChange(this.player, PlayerInventoryTransaction.EventCreator.STANDARD); - this.player.inventoryMenu.broadcastChanges(); - } - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/BlockMixin_Forge_Tracker.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/BlockMixin_Forge_Tracker.java deleted file mode 100755 index 64005dd321a..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/BlockMixin_Forge_Tracker.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.tracker.world.level.block; - - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import org.spongepowered.common.bridge.RegistryBackedTrackableBridge; -import org.spongepowered.forge.mixin.tracker.world.level.block.state.BlockBehaviorMixin_Forge_Tracker; - -@Mixin(Block.class) -public abstract class BlockMixin_Forge_Tracker extends BlockBehaviorMixin_Forge_Tracker implements RegistryBackedTrackableBridge { - - //@formatter:off - @Shadow public abstract BlockState defaultBlockState(); - //@formatter:on - - @Override - protected void forgeTracker$initializeTrackingState(CallbackInfoReturnable cir) { - // TODO Not the best check but the tracker options only matter during block ticks... - if (this.isRandomlyTicking(this.defaultBlockState())) { - this.bridge$refreshTrackerStates(); - } - } -} diff --git a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/state/BlockBehaviorMixin_Forge_Tracker.java b/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/state/BlockBehaviorMixin_Forge_Tracker.java deleted file mode 100755 index 8784263a379..00000000000 --- a/neoforge/src/mixins/java/org/spongepowered/forge/mixin/tracker/world/level/block/state/BlockBehaviorMixin_Forge_Tracker.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of Sponge, licensed under the MIT License (MIT). - * - * Copyright (c) SpongePowered - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.spongepowered.forge.mixin.tracker.world.level.block.state; - - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -@Mixin(BlockBehaviour.class) -public abstract class BlockBehaviorMixin_Forge_Tracker { - @Shadow protected abstract boolean isRandomlyTicking(BlockState $$0); - - @Inject( - method = "getLootTable", - at = @At( - value = "FIELD", - target = "Lnet/minecraft/world/level/block/state/BlockBehaviour;lootTableSupplier:Ljava/util/function/Supplier;", - remap = false - ) - ) - protected void forgeTracker$initializeTrackingState(CallbackInfoReturnable cir) { - } -} diff --git a/neoforge/src/mixins/resources/mixins.spongeforge.api.json b/neoforge/src/mixins/resources/mixins.spongeforge.api.json deleted file mode 100755 index afbe11ab0d7..00000000000 --- a/neoforge/src/mixins/resources/mixins.spongeforge.api.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.spongepowered.forge.mixin.api", - "target": "@env(DEFAULT)", - "compatibilityLevel": "JAVA_8", - "priority": 1300, - "mixins": [ - "minecraft.server.MinecraftServerMixin_Forge_API" - ], - "overwrites": { - "conformVisibility": true - } -} diff --git a/neoforge/src/mixins/resources/mixins.spongeforge.core.json b/neoforge/src/mixins/resources/mixins.spongeforge.core.json deleted file mode 100755 index 2a80060ac44..00000000000 --- a/neoforge/src/mixins/resources/mixins.spongeforge.core.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.spongepowered.forge.mixin.core", - "plugin": "org.spongepowered.forge.mixin.plugin.ForgeCorePlugin", - "target": "@env(DEFAULT)", - "compatibilityLevel": "JAVA_8", - "priority": 1301, - "mixins": [ - "api.event.EventMixin_Forge", - "api.event.block.ChangeBlockEvent_AllMixin_Forge", - "api.event.entity.ChangeEntityWorldEvent_PreMixin_Forge", - "api.event.entity.ChangeEventWorldEvent_PostMixin_Forge", - "commands.CommandsMixin_Forge", - "minecraftforge.MinecraftForgeMixin_Forge", - "minecraftforge.event.entity.EntityTravelToDimensionEventMixin_Forge", - "minecraftforge.event.entity.player.PlayerEvent_PlayerChangedDimensionEventMixin_Forge", - "minecraftforge.event.world.BlockEvent_BreakEventMixin_Forge", - "minecraftforge.event.world.BlockEventMixin_Forge", - "minecraftforge.internal.BrandingControlMixin_Forge", - "minecraftforge.registries.ForgeRegistryMixin_Forge", - "minecraftforge.registries.RegistryManagerMixin_Forge", - "network.ConnectionMixin_Forge", - "server.BootstrapMixin_Forge", - "server.MinecraftServerMixin_Forge", - "server.commands.SpreadPlayersCommandMixin_Forge", - "server.level.ServerPlayerMixin_Forge", - "server.network.ServerGamePacketListenerImplMixin_Forge", - "server.network.ServerLoginPacketListenerImplMixin_Forge", - "world.entity.LivingEntityMixin_Forge", - "world.entity.LivingEntityMixin_Forge_Attack_Impl", - "world.entity.item.ItemEntityMixin_Forge", - "world.entity.player.PlayerMixin_Forge", - "world.entity.projectile.ThrownEnderpealMixin_Forge", - "world.entity.vehicle.BoatMixin_Forge", - "world.level.block.FireBlockMixin_Forge", - "world.level.block.entity.AbstractFurnaceBlockEntityMixin_Forge" - ], - "client": [ - "client.MinecraftMixin_Forge", - "client.main.MainMixin_Forge" - ], - "server": [ - "server.MainMixin_Forge" - ] -} diff --git a/neoforge/src/mixins/resources/mixins.spongeforge.inventory.json b/neoforge/src/mixins/resources/mixins.spongeforge.inventory.json deleted file mode 100755 index ac8b6037eac..00000000000 --- a/neoforge/src/mixins/resources/mixins.spongeforge.inventory.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.spongepowered.forge.mixin.inventory", - "plugin": "org.spongepowered.forge.mixin.plugin.ForgeCorePlugin", - "target": "@env(DEFAULT)", - "priority": 1300, - "mixins": [ - "event.world.level.block.entity.HopperBlockEntityMixin_Inventory_Forge" - ] -} diff --git a/neoforge/src/mixins/resources/mixins.spongeforge.tracker.json b/neoforge/src/mixins/resources/mixins.spongeforge.tracker.json deleted file mode 100755 index 3061f2ca8ce..00000000000 --- a/neoforge/src/mixins/resources/mixins.spongeforge.tracker.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "org.spongepowered.forge.mixin.tracker", - "target": "@env(DEFAULT)", - "compatibilityLevel": "JAVA_8", - "priority": 1302, - "mixins": [ - "server.level.ServerPlayerGameModeMixin_Forge_Tracker", - "world.level.block.BlockMixin_Forge_Tracker", - "world.level.block.state.BlockBehaviorMixin_Forge_Tracker" - ] -} From d1b5bb7c4f6537cff64da19fd773ae71ab0a2964 Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Wed, 21 Aug 2024 04:42:00 +0700 Subject: [PATCH 04/13] Initial NeoForge support --- forge/build.gradle.kts | 18 +++-- forge/gradle.properties | 10 +-- .../PluginDependencyConfigurable.java | 5 +- .../metadata/PluginFileConfigurable.java | 2 +- .../metadata/PluginMetadataConfigurable.java | 3 +- .../loading/metadata/PluginMetadataUtils.java | 5 +- .../loading/moddiscovery/ModFileParsers.java | 29 +++++--- .../SpongeForgeDependencyLocator.java | 58 ++++++--------- .../moddiscovery/SpongeForgeModLocator.java | 54 ++++++++------ .../locator/EnvironmentPluginLocator.java | 38 +++++++--- .../locator/PluginsDirectoryLocator.java | 44 +++++++---- .../applaunch/plugin/ForgePluginPlatform.java | 4 +- .../transformation/ListenerTransformer.java | 34 ++++----- .../SpongeForgeTransformationService.java | 16 ++-- .../provider/JavaPluginLanguageProvider.java | 48 +++++++----- .../forge/launch/ForgeLaunch.java | 7 +- .../forge/launch/ForgeMappingManager.java | 2 +- .../bridge/event/SpongeEventBridge_Forge.java | 12 +-- .../launch/command/ForgeCommandManager.java | 10 ++- .../forge/launch/event/ForgeEventManager.java | 74 +++++++------------ .../forge/launch/event/SpongeEventBus.java | 56 +------------- .../launch/inject/SpongeForgeModule.java | 6 +- .../launch/plugin/ForgePluginContainer.java | 9 ++- .../launch/plugin/ForgePluginManager.java | 9 ++- .../org/spongepowered/forge/SpongeAPIMod.java | 2 +- .../spongepowered/forge/SpongeForgeMod.java | 43 +++++------ .../org/spongepowered/forge/SpongeMod.java | 2 +- .../forge/hook/ForgeChannelHooks.java | 7 +- .../forge/hook/ForgeEventHooks.java | 8 +- .../forge/hook/ForgeGeneralHooks.java | 3 +- .../forge/hook/ForgeWorldHooks.java | 8 +- .../MinecraftForgeMixin_Forge.java | 12 +-- ...AbstractFurnaceBlockEntityMixin_Forge.java | 3 +- 33 files changed, 313 insertions(+), 328 deletions(-) diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts index 813a250e365..571443d18de 100644 --- a/forge/build.gradle.kts +++ b/forge/build.gradle.kts @@ -6,6 +6,9 @@ buildscript { maven("https://repo.spongepowered.org/repository/maven-public") { name = "sponge" } + maven("https://maven.neoforged.net/releases/") { + name = "neoforge" + } maven("https://maven.architectury.dev/") } } @@ -21,7 +24,7 @@ val commonProject = parent!! val transformersProject = parent!!.project(":modlauncher-transformers") val apiVersion: String by project val minecraftVersion: String by project -val forgeVersion: String by project +val neoForgeVersion: String by project val recommendedVersion: String by project val organization: String by project val projectUrl: String by project @@ -29,12 +32,15 @@ val projectUrl: String by project val testPluginsProject: Project? = rootProject.subprojects.find { "testplugins" == it.name } description = "The SpongeAPI implementation for MinecraftForge" -version = spongeImpl.generatePlatformBuildVersionString(apiVersion, minecraftVersion, recommendedVersion, forgeVersion) +version = spongeImpl.generatePlatformBuildVersionString(apiVersion, minecraftVersion, recommendedVersion, neoForgeVersion) repositories { maven("https://repo.spongepowered.org/repository/maven-public/") { name = "sponge" } + maven("https://maven.neoforged.net/releases/") { + name = "neoforge" + } } // SpongeForge libraries @@ -158,8 +164,8 @@ extensions.configure(LoomGradleExtensionAPI::class) { useLegacyMixinAp.set(false) } - forge { - useCustomMixin.set(false) + neoForge { + } mods { @@ -186,7 +192,7 @@ extensions.configure(LoomGradleExtensionAPI::class) { dependencies { "minecraft"("com.mojang:minecraft:${minecraftVersion}") - "forge"("net.minecraftforge:forge:$minecraftVersion-$forgeVersion") + "neoForge"("net.neoforged:neoforge:$neoForgeVersion") "mappings"(loom.layered { officialMojangMappings { nameSyntheticMembers = true @@ -249,7 +255,7 @@ val forgeManifest = java.manifest { "Specification-Vendor" to "SpongePowered", "Specification-Version" to apiVersion, "Implementation-Title" to project.name, - "Implementation-Version" to spongeImpl.generatePlatformBuildVersionString(apiVersion, minecraftVersion, recommendedVersion, forgeVersion), + "Implementation-Version" to spongeImpl.generatePlatformBuildVersionString(apiVersion, minecraftVersion, recommendedVersion, neoForgeVersion), "Implementation-Vendor" to "SpongePowered" ) // These two are included by most CI's diff --git a/forge/gradle.properties b/forge/gradle.properties index 6617e1b146e..1c271bdaa7f 100644 --- a/forge/gradle.properties +++ b/forge/gradle.properties @@ -1,8 +1,8 @@ -name=SpongeForge -implementation=Forge -description=The SpongeAPI implementation for MinecraftForge +name=SpongeNeoForge +implementation=NeoForge +description=The SpongeAPI implementation for MinecraftNeoForge -forgeVersion=52.0.3 -loom.platform=forge +neoForgeVersion=21.1.1 +loom.platform=neoforge fabric.loom.dontRemap=true mixinConfigs=mixins.spongeforge.accessors.json,mixins.spongeforge.api.json,mixins.spongeforge.inventory.json,mixins.spongeforge.core.json,mixins.spongeforge.tracker.json \ No newline at end of file diff --git a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginDependencyConfigurable.java b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginDependencyConfigurable.java index b72a3026397..a52ee64b10d 100644 --- a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginDependencyConfigurable.java +++ b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginDependencyConfigurable.java @@ -24,8 +24,9 @@ */ package org.spongepowered.forge.applaunch.loading.metadata; -import net.minecraftforge.forgespi.language.IConfigurable; -import net.minecraftforge.forgespi.language.IModInfo; +import net.neoforged.neoforgespi.language.IConfigurable; +import net.neoforged.neoforgespi.language.IModInfo; + import org.spongepowered.plugin.metadata.PluginMetadata; import org.spongepowered.plugin.metadata.model.PluginDependency; diff --git a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginFileConfigurable.java b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginFileConfigurable.java index 05d3da27b42..547bf67c77c 100644 --- a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginFileConfigurable.java +++ b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginFileConfigurable.java @@ -24,7 +24,7 @@ */ package org.spongepowered.forge.applaunch.loading.metadata; -import net.minecraftforge.forgespi.language.IConfigurable; +import net.neoforged.neoforgespi.language.IConfigurable; import org.spongepowered.plugin.metadata.PluginMetadata; import org.spongepowered.plugin.metadata.builtin.MetadataContainer; import org.spongepowered.plugin.metadata.model.PluginDependency; diff --git a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataConfigurable.java b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataConfigurable.java index 95584102d07..98567a39639 100644 --- a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataConfigurable.java +++ b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataConfigurable.java @@ -24,7 +24,8 @@ */ package org.spongepowered.forge.applaunch.loading.metadata; -import net.minecraftforge.forgespi.language.IConfigurable; +import net.neoforged.neoforgespi.language.IConfigurable; + import org.spongepowered.plugin.metadata.PluginMetadata; import java.util.Collections; diff --git a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataUtils.java b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataUtils.java index 1ffd3c8c854..3a40bca1feb 100644 --- a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataUtils.java +++ b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/metadata/PluginMetadataUtils.java @@ -24,8 +24,9 @@ */ package org.spongepowered.forge.applaunch.loading.metadata; -import net.minecraftforge.fml.loading.moddiscovery.ModInfo; -import net.minecraftforge.forgespi.language.IModInfo; +import net.neoforged.fml.loading.moddiscovery.ModInfo; +import net.neoforged.neoforgespi.language.IModInfo; + import org.spongepowered.plugin.metadata.PluginMetadata; import org.spongepowered.plugin.metadata.builtin.StandardPluginMetadata; import org.spongepowered.plugin.metadata.builtin.model.StandardPluginContributor; diff --git a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/ModFileParsers.java b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/ModFileParsers.java index de41a11126b..fa4d4c3a8c8 100644 --- a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/ModFileParsers.java +++ b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/ModFileParsers.java @@ -25,13 +25,13 @@ package org.spongepowered.forge.applaunch.loading.moddiscovery; import cpw.mods.jarhandling.SecureJar; -import net.minecraftforge.fml.loading.moddiscovery.ModFile; -import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; -import net.minecraftforge.fml.loading.moddiscovery.ModJarMetadata; -import net.minecraftforge.forgespi.language.IModFileInfo; -import net.minecraftforge.forgespi.locating.IModFile; -import net.minecraftforge.forgespi.locating.IModLocator; -import net.minecraftforge.forgespi.locating.ModFileFactory; + +import net.neoforged.fml.loading.moddiscovery.ModFile; +import net.neoforged.fml.loading.moddiscovery.ModFileInfo; +import net.neoforged.fml.loading.moddiscovery.ModJarMetadata; +import net.neoforged.neoforgespi.language.IModFileInfo; +import net.neoforged.neoforgespi.locating.*; + import org.spongepowered.common.applaunch.AppLaunch; import org.spongepowered.common.applaunch.plugin.PluginPlatformConstants; import org.spongepowered.forge.applaunch.loading.metadata.PluginFileConfigurable; @@ -89,9 +89,20 @@ private static ModJarMetadata newModJarMetadata() { } } - public static ModFile newPluginInstance(final IModLocator locator, final Path... path) { + public static ModFile newPluginInstance(final IModFileCandidateLocator locator, final Path... path) { ModJarMetadata mjm = newModJarMetadata(); - ModFile modFile = (ModFile) ModFileFactory.FACTORY.build(SecureJar.from(jar -> mjm, path), locator, ModFileParsers::parsePluginMetadata); + ModFileInfoParser parser = ModFileParsers::parsePluginMetadata; + + ModFile modFile = new ModFile(SecureJar.from(path), parser, ModFileDiscoveryAttributes.DEFAULT.withLocator(locator)); + mjm.setModFile(modFile); + return modFile; + } + + public static ModFile newPluginInstance(final IDependencyLocator locator, final Path... path) { + ModJarMetadata mjm = newModJarMetadata(); + ModFileInfoParser parser = ModFileParsers::parsePluginMetadata; + + ModFile modFile = new ModFile(SecureJar.from(path), parser, ModFileDiscoveryAttributes.DEFAULT.withDependencyLocator(locator)); mjm.setModFile(modFile); return modFile; } diff --git a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeDependencyLocator.java b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeDependencyLocator.java index 28a89f3a523..2757a0fde22 100644 --- a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeDependencyLocator.java +++ b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeDependencyLocator.java @@ -26,31 +26,37 @@ import cpw.mods.modlauncher.Environment; import cpw.mods.modlauncher.Launcher; -import net.minecraftforge.fml.loading.FMLEnvironment; -import net.minecraftforge.fml.loading.moddiscovery.AbstractModProvider; -import net.minecraftforge.forgespi.locating.IDependencyLocator; -import net.minecraftforge.forgespi.locating.IModFile; -import net.minecraftforge.forgespi.locating.IModLocator; + +import net.neoforged.fml.loading.FMLEnvironment; +import net.neoforged.fml.loading.moddiscovery.ModFile; +import net.neoforged.neoforgespi.locating.IDependencyLocator; +import net.neoforged.neoforgespi.locating.IDiscoveryPipeline; +import net.neoforged.neoforgespi.locating.IModFile; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; + import org.spongepowered.forge.applaunch.loading.moddiscovery.library.LibraryManager; import org.spongepowered.forge.applaunch.transformation.SpongeForgeTransformationService; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import java.util.Map; // works with ForgeProductionBootstrap to make this whole thing go -public class SpongeForgeDependencyLocator extends AbstractModProvider implements IDependencyLocator { +public class SpongeForgeDependencyLocator implements IDependencyLocator { private static final Logger LOGGER = LogManager.getLogger(); + private final List modFiles = new ArrayList<>(); - private LibraryManager libraryManager; + final Environment env = Launcher.INSTANCE.environment(); + private LibraryManager libraryManager = new LibraryManager( + env.getProperty(SpongeForgeTransformationService.Keys.CHECK_LIBRARY_HASHES.get()).orElse(true), + env.getProperty(SpongeForgeTransformationService.Keys.LIBRARIES_DIRECTORY.get()) + .orElseThrow(() -> new IllegalStateException("no libraries available")), + SpongeForgeModLocator.class.getResource("libraries.json")); @Override - public List scanMods(Iterable loadedMods) { - final List modFiles = new ArrayList<>(); - + public void scanMods(List loadedMods, IDiscoveryPipeline pipeline) { // Add Sponge-specific libraries if (FMLEnvironment.production) { try { @@ -63,36 +69,14 @@ public List scanMods(Iterable loadedMods) { for (final LibraryManager.Library library : this.libraryManager.getAll().values()) { final Path path = library.getFile(); SpongeForgeDependencyLocator.LOGGER.debug("Proposing jar {} as a game library", path); - - final IModLocator.ModFileOrException fileOrException = createMod(path); - if (fileOrException.ex() != null) { - throw fileOrException.ex(); - } - modFiles.add(fileOrException.file()); + ModFile mod = ModFileParsers.newPluginInstance(this, path); + modFiles.add(mod); } } - - return modFiles; } - @Override - protected String getDefaultJarModType() { - return IModFile.Type.GAMELIBRARY.name(); - } - - @Override - public String name() { - return "spongeforge"; + public List getModFiles() { + return modFiles; } - @Override - public void initArguments(final Map arguments) { - final Environment env = Launcher.INSTANCE.environment(); - this.libraryManager = new LibraryManager( - env.getProperty(SpongeForgeTransformationService.Keys.CHECK_LIBRARY_HASHES.get()).orElse(true), - env.getProperty(SpongeForgeTransformationService.Keys.LIBRARIES_DIRECTORY.get()) - .orElseThrow(() -> new IllegalStateException("no libraries available")), - SpongeForgeModLocator.class.getResource("libraries.json") - ); - } } diff --git a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeModLocator.java b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeModLocator.java index e7c704b506b..c03d28ac3a0 100644 --- a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeModLocator.java +++ b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/SpongeForgeModLocator.java @@ -27,11 +27,16 @@ import com.google.common.collect.ImmutableMap; import cpw.mods.modlauncher.Environment; import cpw.mods.modlauncher.Launcher; -import net.minecraftforge.fml.loading.FMLEnvironment; -import net.minecraftforge.fml.loading.moddiscovery.AbstractModProvider; -import net.minecraftforge.forgespi.locating.IModLocator; + +import net.neoforged.fml.javafmlmod.FMLJavaModLanguageProvider; +import net.neoforged.neoforgespi.ILaunchContext; +import net.neoforged.neoforgespi.locating.IDiscoveryPipeline; +import net.neoforged.neoforgespi.locating.IModFile; +import net.neoforged.neoforgespi.locating.IModFileCandidateLocator; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; + import org.spongepowered.forge.applaunch.plugin.ForgePluginPlatform; import java.net.URI; @@ -39,47 +44,48 @@ import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; -public final class SpongeForgeModLocator extends AbstractModProvider implements IModLocator { +public final class SpongeForgeModLocator extends FMLJavaModLanguageProvider implements IModFileCandidateLocator { private static final Logger LOGGER = LogManager.getLogger(); + private List modFiles = new ArrayList<>(); @Override - public List scanMods() { - if (!FMLEnvironment.production) { - return List.of(); - } - + public void findCandidates(ILaunchContext context, IDiscoveryPipeline pipeline) { try { URL rootJar = SpongeForgeModLocator.class.getProtectionDomain().getCodeSource().getLocation(); FileSystem fs = FileSystems.getFileSystem(rootJar.toURI()); // FML has already opened a file system for this jar - return Files.list(fs.getPath("jars")) - .filter(path -> path.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".jar")) - .map(path -> { - try { - URI jij = new URI("jij:" + path.toAbsolutePath().toUri().getRawSchemeSpecificPart()).normalize(); - final Map env = ImmutableMap.of("packagePath", path); - FileSystem jijFS = FileSystems.newFileSystem(jij, env); - return jijFS.getPath("/"); // root of the archive to load - } catch (Exception e) { - throw new RuntimeException(e); - } - }).map(this::createMod).toList(); + modFiles = Files.list(fs.getPath("jars")) + .filter(path -> path.getFileName().toString().toLowerCase(Locale.ROOT).endsWith(".jar")) + .map(path -> { + try { + URI jij = new URI("jij:" + path.toAbsolutePath().toUri().getRawSchemeSpecificPart()).normalize(); + final Map env = ImmutableMap.of("packagePath", path); + FileSystem jijFS = FileSystems.newFileSystem(jij, env); + return jijFS.getPath("/"); // root of the archive to load + } catch (Exception e) { + return null; + } + }).filter(path -> path != null).map(this::createMod).toList(); } catch (Exception e) { LOGGER.error("Failed to scan mod candidates", e); } + } - return List.of(); + private IModFile createMod(Path path) { + return ModFileParsers.newPluginInstance(this, path); } @Override public String name() { - return "spongeforge"; + return "spongeneoforge"; } - @Override + //@Override public void initArguments(Map arguments) { final Environment env = Launcher.INSTANCE.environment(); ForgePluginPlatform.bootstrap(env); diff --git a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/EnvironmentPluginLocator.java b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/EnvironmentPluginLocator.java index 4aa59a6cd64..02b0b181508 100644 --- a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/EnvironmentPluginLocator.java +++ b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/EnvironmentPluginLocator.java @@ -24,8 +24,12 @@ */ package org.spongepowered.forge.applaunch.loading.moddiscovery.locator; -import net.minecraftforge.fml.loading.moddiscovery.AbstractModProvider; -import net.minecraftforge.forgespi.locating.IModLocator; +import net.neoforged.fml.javafmlmod.FMLJavaModLanguageProvider; +import net.neoforged.neoforgespi.ILaunchContext; +import net.neoforged.neoforgespi.language.ModFileScanData; +import net.neoforged.neoforgespi.locating.IDiscoveryPipeline; +import net.neoforged.neoforgespi.locating.IModFileCandidateLocator; + import org.spongepowered.forge.applaunch.loading.moddiscovery.ModFileParsers; import java.nio.file.Path; @@ -35,20 +39,34 @@ import java.util.Map; import java.util.stream.Stream; -public final class EnvironmentPluginLocator extends AbstractModProvider implements IModLocator { +public final class EnvironmentPluginLocator extends FMLJavaModLanguageProvider implements IModFileCandidateLocator { @Override - public List scanMods() { - final List modFiles = new ArrayList<>(); + public void findCandidates(ILaunchContext context, IDiscoveryPipeline pipeline) { + for(Path[] arrayPaths : getPluginsPaths()) for(Path path : arrayPaths) context.addLocated(path); + scanMods().forEach(scan -> { + scan.getIModInfoData().forEach(file -> { + pipeline.addModFile(file.getFile()); + context.addLocated(file.getFile().getFilePath()); + }); + }); + } + + //@Override + public List scanMods() { + final List modFiles = new ArrayList<>(); for (final Path[] paths : getPluginsPaths()) { - modFiles.add(new ModFileOrException(ModFileParsers.newPluginInstance(this, paths), null)); + ModFileScanData data = new ModFileScanData(); + data.addModFileInfo(ModFileParsers.newPluginInstance(this, paths).getModFileInfo()); } return modFiles; } - @Override - protected ModFileOrException createMod(Path path) { - return new ModFileOrException(ModFileParsers.newPluginInstance(this, path), null); + //@Override + protected ModFileScanData createMod(Path path) { + ModFileScanData data = new ModFileScanData(); + data.addModFileInfo(ModFileParsers.newPluginInstance(this, path).getModFileInfo()); + return data; } @Override @@ -56,7 +74,7 @@ public String name() { return "environment plugin"; } - @Override + //@Override public void initArguments(final Map arguments) { } diff --git a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/PluginsDirectoryLocator.java b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/PluginsDirectoryLocator.java index f4911cae3b5..8a1211aae7f 100644 --- a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/PluginsDirectoryLocator.java +++ b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/loading/moddiscovery/locator/PluginsDirectoryLocator.java @@ -24,14 +24,20 @@ */ package org.spongepowered.forge.applaunch.loading.moddiscovery.locator; -import cpw.mods.modlauncher.api.LamdbaExceptionUtils; -import net.minecraftforge.fml.loading.ModDirTransformerDiscoverer; -import net.minecraftforge.fml.loading.StringUtils; -import net.minecraftforge.fml.loading.moddiscovery.AbstractModProvider; -import net.minecraftforge.fml.loading.moddiscovery.ModFile; -import net.minecraftforge.forgespi.locating.IModLocator; +import cpw.mods.util.LambdaExceptionUtils; + +import net.neoforged.fml.javafmlmod.FMLJavaModLanguageProvider; +import net.neoforged.fml.loading.ModDirTransformerDiscoverer; +import net.neoforged.fml.loading.StringUtils; +import net.neoforged.fml.loading.moddiscovery.ModFile; +import net.neoforged.neoforgespi.ILaunchContext; +import net.neoforged.neoforgespi.language.ModFileScanData; +import net.neoforged.neoforgespi.locating.IDiscoveryPipeline; +import net.neoforged.neoforgespi.locating.IModFileCandidateLocator; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; + import org.spongepowered.common.applaunch.AppLaunch; import org.spongepowered.forge.applaunch.loading.moddiscovery.ModFileParsers; @@ -43,26 +49,28 @@ import java.util.Map; import java.util.stream.Stream; -public final class PluginsDirectoryLocator extends AbstractModProvider implements IModLocator { +public final class PluginsDirectoryLocator extends FMLJavaModLanguageProvider implements IModFileCandidateLocator { private static final Logger LOGGER = LogManager.getLogger(); + final List modFiles = new ArrayList<>(); + @Override - public List scanMods() { + public void findCandidates(ILaunchContext context, IDiscoveryPipeline pipeline) { final List pluginDirectories = AppLaunch.pluginPlatform().pluginDirectories(); - final List modFiles = new ArrayList<>(); - - for (final Path pluginDirectory : pluginDirectories) { - PluginsDirectoryLocator.LOGGER.debug("Scanning plugins directory '{}' for plugins", pluginDirectory); - this.scanForModsIn(pluginDirectory).map((f) -> new ModFileOrException(f, null)).forEach(modFiles::add); + for (final Path paths : pluginDirectories) { + this.scanForModsIn(paths).forEach(this::addData); } + } + public List getScanData() { return modFiles; } private Stream scanForModsIn(final Path pluginsDirectory) { + final List excluded = ModDirTransformerDiscoverer.allExcluded(); - return LamdbaExceptionUtils.uncheck(() -> Files.list(pluginsDirectory)) + return LambdaExceptionUtils.uncheck(() -> Files.list(pluginsDirectory)) .filter((p) -> !excluded.contains(p) && StringUtils.toLowerCase(p.getFileName().toString()).endsWith(".jar")) .sorted(Comparator.comparing((path) -> StringUtils.toLowerCase(path.getFileName().toString()))) .map((p) -> ModFileParsers.newPluginInstance(this, p)) @@ -74,7 +82,13 @@ public String name() { return "plugins directory"; } - @Override + //@Override public void initArguments(final Map arguments) { } + + private void addData(ModFile modFile) { + ModFileScanData data = new ModFileScanData(); + data.addModFileInfo(modFile.getModFileInfo()); + modFiles.add(data); + } } diff --git a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/plugin/ForgePluginPlatform.java b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/plugin/ForgePluginPlatform.java index f054ca99da1..6ba748612e1 100644 --- a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/plugin/ForgePluginPlatform.java +++ b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/plugin/ForgePluginPlatform.java @@ -26,7 +26,9 @@ import cpw.mods.modlauncher.Environment; import cpw.mods.modlauncher.api.IEnvironment; -import net.minecraftforge.fml.loading.FMLPaths; + +import net.neoforged.fml.loading.FMLPaths; + import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.spongepowered.common.applaunch.AppLaunch; diff --git a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/ListenerTransformer.java b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/ListenerTransformer.java index 62daa6ab20e..3990525693b 100644 --- a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/ListenerTransformer.java +++ b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/ListenerTransformer.java @@ -24,29 +24,19 @@ */ package org.spongepowered.forge.applaunch.transformation; -import static org.objectweb.asm.Opcodes.ACC_STATIC; -import static org.objectweb.asm.Opcodes.INVOKESTATIC; -import static org.objectweb.asm.Opcodes.RETURN; - -import cpw.mods.modlauncher.api.ITransformer; -import cpw.mods.modlauncher.api.ITransformerActivity; -import cpw.mods.modlauncher.api.ITransformerVotingContext; -import cpw.mods.modlauncher.api.TransformerVoteResult; -import net.minecraftforge.fml.loading.LoadingModList; -import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; -import net.minecraftforge.forgespi.language.ModFileScanData; +import cpw.mods.modlauncher.api.*; +import net.neoforged.fml.loading.LoadingModList; +import net.neoforged.fml.loading.moddiscovery.ModFileInfo; +import net.neoforged.neoforgespi.language.ModFileScanData; import org.checkerframework.checker.nullness.qual.NonNull; import org.objectweb.asm.Type; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.InsnList; -import org.objectweb.asm.tree.InsnNode; -import org.objectweb.asm.tree.LdcInsnNode; -import org.objectweb.asm.tree.MethodInsnNode; -import org.objectweb.asm.tree.MethodNode; +import org.objectweb.asm.tree.*; import java.util.HashSet; import java.util.Set; +import static org.objectweb.asm.Opcodes.*; + public class ListenerTransformer implements ITransformer { @NonNull @@ -83,9 +73,8 @@ public TransformerVoteResult castVote(final ITransformerVotingContext context) { return context.getReason().equals(ITransformerActivity.CLASSLOADING_REASON) ? TransformerVoteResult.YES : TransformerVoteResult.NO; } - @NonNull @Override - public Set targets() { + public Set> targets() { final Type listenerType = Type.getType("Lorg/spongepowered/api/event/Listener;"); final Set listenerClasses = new HashSet<>(); @@ -97,10 +86,15 @@ public Set targets() { } } - final Set targets = new HashSet<>(); + final Set> targets = new HashSet<>(); for (Type listener : listenerClasses) { targets.add(Target.targetClass(listener.getInternalName())); } return targets; } + + @Override + public TargetType getTargetType() { + return TargetType.CLASS; + } } diff --git a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/SpongeForgeTransformationService.java b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/SpongeForgeTransformationService.java index 2bde9d692b7..0849a65b284 100644 --- a/forge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/SpongeForgeTransformationService.java +++ b/forge/src/applaunch/java/org/spongepowered/forge/applaunch/transformation/SpongeForgeTransformationService.java @@ -27,15 +27,13 @@ import cpw.mods.jarhandling.SecureJar; import cpw.mods.modlauncher.Environment; import cpw.mods.modlauncher.Launcher; -import cpw.mods.modlauncher.api.IEnvironment; -import cpw.mods.modlauncher.api.IModuleLayerManager; -import cpw.mods.modlauncher.api.ITransformationService; -import cpw.mods.modlauncher.api.ITransformer; -import cpw.mods.modlauncher.api.TypesafeMap; +import cpw.mods.modlauncher.api.*; + import joptsimple.OptionSpec; import joptsimple.OptionSpecBuilder; -import net.minecraftforge.fml.loading.LoadingModList; -import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; + +import net.neoforged.fml.loading.LoadingModList; +import net.neoforged.fml.loading.moddiscovery.ModFileInfo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.checkerframework.checker.nullness.qual.NonNull; @@ -140,10 +138,8 @@ public List completeScan(IModuleLayerManager layerManager) { return List.of(); } - @NonNull @Override - @SuppressWarnings("rawtypes") // :) - public List transformers() { + public List> transformers() { return List.of(new ListenerTransformer()); } diff --git a/forge/src/lang/java/org/spongepowered/forge/lang/provider/JavaPluginLanguageProvider.java b/forge/src/lang/java/org/spongepowered/forge/lang/provider/JavaPluginLanguageProvider.java index 5bdcef45012..c0ecc3175d5 100644 --- a/forge/src/lang/java/org/spongepowered/forge/lang/provider/JavaPluginLanguageProvider.java +++ b/forge/src/lang/java/org/spongepowered/forge/lang/provider/JavaPluginLanguageProvider.java @@ -24,13 +24,15 @@ */ package org.spongepowered.forge.lang.provider; -import cpw.mods.modlauncher.api.LamdbaExceptionUtils; -import net.minecraftforge.fml.Logging; -import net.minecraftforge.fml.ModLoadingStage; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLanguageProvider; -import net.minecraftforge.forgespi.language.IModInfo; -import net.minecraftforge.forgespi.language.IModLanguageProvider; -import net.minecraftforge.forgespi.language.ModFileScanData; +import cpw.mods.util.LambdaExceptionUtils; +import net.neoforged.fml.Logging; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.ModLoadingContext; +import net.neoforged.fml.ModLoadingException; +import net.neoforged.fml.javafmlmod.FMLJavaModLanguageProvider; +import net.neoforged.neoforgespi.language.IModInfo; +import net.neoforged.neoforgespi.language.IModLanguageLoader; +import net.neoforged.neoforgespi.language.ModFileScanData; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.objectweb.asm.Type; @@ -56,7 +58,7 @@ public JavaPluginLanguageProvider() { public String name() { return "java_plain"; } - +/* @Override public Consumer getFileVisitor() { return scanResult -> { @@ -67,9 +69,9 @@ public Consumer getFileVisitor() { .collect(Collectors.toMap(PluginTarget::getPlugin, Function.identity(), (a,b)->a)); scanResult.addLanguageLoader(modTargetMap); }; - } + }*/ - private static final class PluginTarget implements IModLanguageProvider.IModLanguageLoader { + private static final class PluginTarget implements IModLanguageLoader { private final Logger logger; private final String className; @@ -82,7 +84,7 @@ private PluginTarget(final String className, final String plugin) { } @Override - public T loadMod(final IModInfo info, final ModFileScanData modFileScanData, final ModuleLayer gameLayer) { + public ModContainer loadMod(final IModInfo info, final ModFileScanData modFileScanData, final ModuleLayer gameLayer) { // The following is adapted from FMLJavaModLanguageProvider.FMLModTarget // This language class is loaded in the system level classloader - before the game even starts @@ -93,30 +95,40 @@ public T loadMod(final IModInfo info, final ModFileScanData modFileScanData, "org.spongepowered.forge.launch.plugin.PluginModContainer", true, Thread.currentThread().getContextClassLoader()); this.logger.debug(Logging.LOADING, "Loading PluginModContainer from classloader {} - got {}", Thread.currentThread().getContextClassLoader(), pluginContainer.getClassLoader()); final Constructor constructor = pluginContainer.getConstructor(IModInfo.class, String.class, ModFileScanData.class, ModuleLayer.class); - return (T) constructor.newInstance(info, className, modFileScanData, gameLayer); + return (ModContainer) constructor.newInstance(info, className, modFileScanData, gameLayer); } // ALL exception handling has to be done through the classloader, because we're loaded in the wrong context, so any classes we just blind load will be in the wrong // class loading context. Funky but works. catch (final InvocationTargetException e) { this.logger.fatal(Logging.LOADING, "Failed to build plugin", e); - final Class mle = (Class) LamdbaExceptionUtils.uncheck(()->Class.forName("net.minecraftforge.fml.ModLoadingException", true, Thread.currentThread().getContextClassLoader())); + final Class mle = (Class) LambdaExceptionUtils.uncheck(()->Class.forName("net.neoforged.fml.ModLoadingException", true, Thread.currentThread().getContextClassLoader())); if (mle.isInstance(e.getTargetException())) { throw mle.cast(e.getTargetException()); } else { - final Class mls = (Class) LamdbaExceptionUtils.uncheck(()->Class.forName("net.minecraftforge.fml.ModLoadingStage", true, Thread.currentThread().getContextClassLoader())); - throw LamdbaExceptionUtils.uncheck(()->LamdbaExceptionUtils.uncheck(()->mle.getConstructor(IModInfo.class, mls, String.class, Throwable.class)).newInstance(info, Enum.valueOf(mls, "CONSTRUCT"), "fml.modloading.failedtoloadmodclass", e)); + final Class mls = (Class) LambdaExceptionUtils.uncheck(()->Class.forName("net.neoforged.fml.ModLoadingContext", true, Thread.currentThread().getContextClassLoader())); + throw LambdaExceptionUtils.uncheck(()->LambdaExceptionUtils.uncheck(()->mle.getConstructor(IModInfo.class, mls, String.class, Throwable.class)).newInstance(info, mls, "fml.modloading.failedtoloadmodclass", e)); } } catch (final NoSuchMethodException | ClassNotFoundException | InstantiationException | IllegalAccessException e) { this.logger.fatal(Logging.LOADING,"Unable to load PluginModContainer, excuse me?", e); - final Class mle = (Class)LamdbaExceptionUtils.uncheck(()->Class.forName("net.minecraftforge.fml.ModLoadingException", true, Thread.currentThread().getContextClassLoader())); - final Class mls = (Class) LamdbaExceptionUtils.uncheck(()->Class.forName("net.minecraftforge.fml.ModLoadingStage", true, Thread.currentThread().getContextClassLoader())); - throw LamdbaExceptionUtils.uncheck(()->LamdbaExceptionUtils.uncheck(()->mle.getConstructor(IModInfo.class, mls, String.class, Throwable.class)).newInstance(info, Enum.valueOf(mls, "CONSTRUCT"), "fml.modloading.failedtoloadmodclass", e)); + final Class mle = (Class)LambdaExceptionUtils.uncheck(()->Class.forName("net.neoforged.fml.ModLoadingException", true, Thread.currentThread().getContextClassLoader())); + final Class mls = (Class) LambdaExceptionUtils.uncheck(()->Class.forName("net.neoforged.fml.ModLoadingContext", true, Thread.currentThread().getContextClassLoader())); + throw LambdaExceptionUtils.uncheck(()->LambdaExceptionUtils.uncheck(()->mle.getConstructor(IModInfo.class, mls, String.class, Throwable.class)).newInstance(info, mls, "fml.modloading.failedtoloadmodclass", e)); } } public String getPlugin() { return this.plugin; } + + @Override + public String name() { + return ""; + } + + @Override + public String version() { + return ""; + } } } diff --git a/forge/src/launch/java/org/spongepowered/forge/launch/ForgeLaunch.java b/forge/src/launch/java/org/spongepowered/forge/launch/ForgeLaunch.java index 5fc342b4229..3c96f27755d 100644 --- a/forge/src/launch/java/org/spongepowered/forge/launch/ForgeLaunch.java +++ b/forge/src/launch/java/org/spongepowered/forge/launch/ForgeLaunch.java @@ -29,9 +29,10 @@ import com.google.inject.Injector; import com.google.inject.Module; import com.google.inject.Stage; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.fml.loading.FMLLoader; -import net.minecraftforge.fml.loading.moddiscovery.ModInfo; + +import net.neoforged.api.distmarker.Dist; +import net.neoforged.fml.loading.FMLLoader; +import net.neoforged.fml.loading.moddiscovery.ModInfo; import org.spongepowered.common.applaunch.plugin.PluginPlatform; import org.spongepowered.common.inject.SpongeCommonModule; import org.spongepowered.common.inject.SpongeModule; diff --git a/forge/src/launch/java/org/spongepowered/forge/launch/ForgeMappingManager.java b/forge/src/launch/java/org/spongepowered/forge/launch/ForgeMappingManager.java index c9f76a458db..5f994c49899 100644 --- a/forge/src/launch/java/org/spongepowered/forge/launch/ForgeMappingManager.java +++ b/forge/src/launch/java/org/spongepowered/forge/launch/ForgeMappingManager.java @@ -25,7 +25,7 @@ package org.spongepowered.forge.launch; import com.google.common.collect.ImmutableMap; -import net.minecraftforge.fml.loading.FMLEnvironment; +import net.neoforged.fml.loading.FMLEnvironment; import org.spongepowered.common.launch.mapping.SpongeMappingManager; import java.util.Map; diff --git a/forge/src/launch/java/org/spongepowered/forge/launch/bridge/event/SpongeEventBridge_Forge.java b/forge/src/launch/java/org/spongepowered/forge/launch/bridge/event/SpongeEventBridge_Forge.java index 883959d5d1e..c8e4b64be36 100644 --- a/forge/src/launch/java/org/spongepowered/forge/launch/bridge/event/SpongeEventBridge_Forge.java +++ b/forge/src/launch/java/org/spongepowered/forge/launch/bridge/event/SpongeEventBridge_Forge.java @@ -24,9 +24,7 @@ */ package org.spongepowered.forge.launch.bridge.event; -import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.eventbus.api.IEventBusInvokeDispatcher; -import net.minecraftforge.eventbus.api.IEventListener; +import net.neoforged.bus.api.Event; import org.checkerframework.checker.nullness.qual.Nullable; import java.util.Collection; @@ -51,9 +49,11 @@ public interface SpongeEventBridge_Forge { * this given event, it can be defined here. * * @return The dispatcher to use. + * + * IEventBusInvokeDispatcher REMOVED IN NEOFORGE! */ - default IEventBusInvokeDispatcher bridge$eventDispatcher() { - return IEventListener::invoke; - } + /*default IEventBusInvokeDispatcher bridge$eventDispatcher() { + return EventListener::invoke; + }*/ } diff --git a/forge/src/launch/java/org/spongepowered/forge/launch/command/ForgeCommandManager.java b/forge/src/launch/java/org/spongepowered/forge/launch/command/ForgeCommandManager.java index 973827201be..035b9af6f1e 100644 --- a/forge/src/launch/java/org/spongepowered/forge/launch/command/ForgeCommandManager.java +++ b/forge/src/launch/java/org/spongepowered/forge/launch/command/ForgeCommandManager.java @@ -31,10 +31,14 @@ import com.mojang.brigadier.context.CommandContextBuilder; import com.mojang.brigadier.context.ParsedArgument; import com.mojang.brigadier.exceptions.CommandSyntaxException; + import net.kyori.adventure.text.Component; + import net.minecraft.commands.CommandSourceStack; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.CommandEvent; + +import net.neoforged.bus.api.EventPriority; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.CommandEvent; import org.spongepowered.api.Game; import org.spongepowered.api.command.CommandCause; import org.spongepowered.api.command.CommandResult; @@ -82,7 +86,7 @@ public CommandResult processCommand(final CommandCause cause, final CommandMappi // Relocated from Commands (injection short circuits it there) final CommandEvent event = new CommandEvent(parseResults); - if (MinecraftForge.EVENT_BUS.post(event)) { + if (!NeoForge.EVENT_BUS.post(EventPriority.NORMAL, event).isCanceled()) { if (event.getException() != null) { Throwables.throwIfUnchecked(event.getException()); } diff --git a/forge/src/launch/java/org/spongepowered/forge/launch/event/ForgeEventManager.java b/forge/src/launch/java/org/spongepowered/forge/launch/event/ForgeEventManager.java index 936129a0765..4f604e67cc0 100644 --- a/forge/src/launch/java/org/spongepowered/forge/launch/event/ForgeEventManager.java +++ b/forge/src/launch/java/org/spongepowered/forge/launch/event/ForgeEventManager.java @@ -25,13 +25,14 @@ package org.spongepowered.forge.launch.event; import com.google.inject.Singleton; -import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.GenericEvent; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.eventbus.api.IEventBusInvokeDispatcher; -import net.minecraftforge.eventbus.api.IEventListener; + +import net.neoforged.bus.api.Event; +import net.neoforged.bus.api.EventListener; +import net.neoforged.bus.api.EventPriority; +import net.neoforged.bus.api.IEventBus; + import org.checkerframework.checker.nullness.qual.Nullable; + import org.spongepowered.common.event.manager.RegisteredListener; import org.spongepowered.common.event.manager.SpongeEventManager; import org.spongepowered.forge.launch.bridge.event.ForgeEventBridge_Forge; @@ -40,7 +41,6 @@ import java.lang.invoke.MethodHandles; import java.util.Collection; -import java.util.Collections; import java.util.List; import java.util.function.Consumer; @@ -66,41 +66,38 @@ public void addListener(final Consumer consumer) { } @Override - public void addListener(final EventPriority priority, final Consumer consumer) { - this.wrappedEventBus.addListener(priority, consumer); + public void addListener(Class eventType, Consumer consumer) { + } @Override - public void addListener(final EventPriority priority, final boolean receiveCancelled, final Consumer consumer) { - this.wrappedEventBus.addListener(priority, receiveCancelled, consumer); + public void addListener(final EventPriority priority, final Consumer consumer) { + this.wrappedEventBus.addListener(priority, consumer); } @Override - public void addListener(final EventPriority priority, final boolean receiveCancelled, final Class eventType, final Consumer consumer) { - this.wrappedEventBus.addListener(priority, receiveCancelled, eventType, consumer); + public void addListener(EventPriority priority, Class eventType, Consumer consumer) { + this.wrappedEventBus.addListener(priority, eventType, consumer); } @Override - public , F> void addGenericListener(final Class genericClassFilter, final Consumer consumer) { - this.wrappedEventBus.addGenericListener(genericClassFilter, consumer); + public void addListener(final EventPriority priority, final boolean receiveCancelled, final Consumer consumer) { + this.wrappedEventBus.addListener(priority, receiveCancelled, consumer); } @Override - public , F> void addGenericListener(final Class genericClassFilter, final EventPriority priority, - final Consumer consumer) { - this.wrappedEventBus.addGenericListener(genericClassFilter, priority, consumer); + public void addListener(final EventPriority priority, final boolean receiveCancelled, final Class eventType, final Consumer consumer) { + this.wrappedEventBus.addListener(priority, receiveCancelled, eventType, consumer); } @Override - public , F> void addGenericListener(final Class genericClassFilter, final EventPriority priority, - final boolean receiveCancelled, final Consumer consumer) { - this.wrappedEventBus.addGenericListener(genericClassFilter, priority, receiveCancelled, consumer); + public void addListener(boolean receiveCanceled, Consumer consumer) { + this.wrappedEventBus.addListener(receiveCanceled, consumer); } @Override - public , F> void addGenericListener(final Class genericClassFilter, final EventPriority priority, - final boolean receiveCancelled, final Class eventType, final Consumer consumer) { - this.wrappedEventBus.addGenericListener(genericClassFilter, priority, receiveCancelled, eventType, consumer); + public void addListener(boolean receiveCanceled, Class eventType, Consumer consumer) { + this.wrappedEventBus.addListener(receiveCanceled, eventType, consumer); } @Override @@ -109,27 +106,13 @@ public void unregister(final Object object) { } @Override - public boolean post(final Event event) { - return this.post(event, IEventListener::invoke); - } - - @Override - public boolean post(final Event event, final IEventBusInvokeDispatcher wrapper) { - if (event instanceof ForgeEventBridge_Forge) { - // intercept! - final ForgeEventBridge_Forge forgeEvent = (ForgeEventBridge_Forge) event; - final org.spongepowered.api.event.@Nullable Event spongeEvent = forgeEvent.bridge$createSpongeEvent(); - if (spongeEvent != null) { - return this.postDualBus(spongeEvent, Collections.singleton(event), wrapper); - } - } - // Do as Forge does - SpongeVanilla has no role to play here. - return this.wrappedEventBus.post(event, wrapper); + public T post(T event) { + return wrappedEventBus.post(event); } @Override - public void shutdown() { - this.wrappedEventBus.shutdown(); + public T post(EventPriority phase, T event) { + return wrappedEventBus.post(phase, event); } @Override @@ -152,13 +135,12 @@ public boolean post(final org.spongepowered.api.event.Event event) { // Do as SpongeVanilla does - Forge has no role to play here. return super.post(event); } - return this.postDualBus(event, forgeEvents, eventBridge.bridge$eventDispatcher()); + return this.postDualBus(event, forgeEvents); } // Implementation - private boolean postDualBus(final org.spongepowered.api.event.Event spongeEvent, final Collection forgeEvents, - final IEventBusInvokeDispatcher dispatcher) { + private boolean postDualBus(final org.spongepowered.api.event.Event spongeEvent, final Collection forgeEvents) { try (final NoExceptionClosable ignored = this.preparePost(spongeEvent)) { final RegisteredListener.Cache listeners = this.getHandlerCache(spongeEvent); final List> beforeModifications = listeners.beforeModifications(); @@ -173,7 +155,7 @@ private boolean postDualBus(final org.spongepowered.api.event.Event spongeEvent, } // Then, we fire all our Forge events for (final Event forgeEvent : forgeEvents) { - this.wrappedEventBus.post(forgeEvent, dispatcher); + this.wrappedEventBus.post(forgeEvent); // We must sync back the event's changes, if there are any. // For complex events, this will be a partial sync. ((ForgeEventBridge_Forge) forgeEvent).bridge$syncTo(spongeEvent); diff --git a/forge/src/launch/java/org/spongepowered/forge/launch/event/SpongeEventBus.java b/forge/src/launch/java/org/spongepowered/forge/launch/event/SpongeEventBus.java index 2d0bbcbacf6..69ff612bd03 100644 --- a/forge/src/launch/java/org/spongepowered/forge/launch/event/SpongeEventBus.java +++ b/forge/src/launch/java/org/spongepowered/forge/launch/event/SpongeEventBus.java @@ -24,18 +24,8 @@ */ package org.spongepowered.forge.launch.event; -import net.minecraftforge.eventbus.BusBuilderImpl; -import net.minecraftforge.eventbus.EventBus; -import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.eventbus.api.EventPriority; -import net.minecraftforge.eventbus.api.IEventBusInvokeDispatcher; -import net.minecraftforge.eventbus.api.IEventExceptionHandler; -import net.minecraftforge.eventbus.api.IEventListener; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.spongepowered.api.event.CauseStackManager; -import org.spongepowered.common.event.manager.SpongeEventManager; -import org.spongepowered.common.event.tracking.PhaseContext; -import org.spongepowered.common.event.tracking.PhaseTracker; +import net.neoforged.bus.*; +import net.neoforged.bus.api.*; import java.lang.reflect.Field; import java.util.Objects; @@ -105,48 +95,6 @@ public SpongeEventBus(final BusBuilderImpl busBuilder) { // Sponge End } - @Override - public boolean post(final Event event, final IEventBusInvokeDispatcher wrapper) { - // @formatter:off - - // Sponge - use the builder/member fields. Avoids reflection but remains very hacky... - if (this.rshutdown) return false; - if (this.rcheckTypesOnDispatch && !rbaseType.isInstance(event)) - { - throw new IllegalArgumentException("Cannot post event of type " + event.getClass().getSimpleName() + " to this event. Must match type: " + this.rbaseType.getSimpleName()); - } - - IEventListener[] listeners = event.getListenerList().getListeners(this.rbusID); - int index = 0; - for (; index < listeners.length; index++) - { - final IEventListener listener = listeners[index]; - if (!this.rtrackPhases && Objects.equals(listener.getClass(), EventPriority.class)) continue; - - try ( - final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame(); - final PhaseContext<@NonNull ?> context = SpongeEventManager.createListenerContext(null)) - { - if (context != null) { - context.buildAndSwitch(); - } - - wrapper.invoke(listener, event); - } catch (final Throwable t) { - this.rexceptionHandler.handleException(this, event, listeners, index, t); - } - } - return event.isCancelable() && event.isCanceled(); - - // @formatter:on - } - - @Override - public void shutdown() { - super.shutdown(); - this.rshutdown = true; - } - @Override public void start() { super.start(); diff --git a/forge/src/launch/java/org/spongepowered/forge/launch/inject/SpongeForgeModule.java b/forge/src/launch/java/org/spongepowered/forge/launch/inject/SpongeForgeModule.java index b9187264f17..fa24af48809 100644 --- a/forge/src/launch/java/org/spongepowered/forge/launch/inject/SpongeForgeModule.java +++ b/forge/src/launch/java/org/spongepowered/forge/launch/inject/SpongeForgeModule.java @@ -25,7 +25,9 @@ package org.spongepowered.forge.launch.inject; import com.google.inject.AbstractModule; -import net.minecraftforge.common.MinecraftForge; + +import net.neoforged.neoforge.common.NeoForge; + import org.spongepowered.api.Platform; import org.spongepowered.api.event.EventManager; import org.spongepowered.common.command.manager.SpongeCommandManager; @@ -38,7 +40,7 @@ public final class SpongeForgeModule extends AbstractModule { @Override protected void configure() { this.bind(Platform.class).to(ForgePlatform.class); - this.bind(EventManager.class).toProvider(() -> (ForgeEventManager) MinecraftForge.EVENT_BUS); + this.bind(EventManager.class).toProvider(() -> (ForgeEventManager) NeoForge.EVENT_BUS); this.bind(SpongeCommandManager.class).to(ForgeCommandManager.class); } diff --git a/forge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginContainer.java b/forge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginContainer.java index 6fceac8462a..ebdbd9999a0 100644 --- a/forge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginContainer.java +++ b/forge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginContainer.java @@ -25,8 +25,8 @@ package org.spongepowered.forge.launch.plugin; import com.google.common.collect.MapMaker; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.loading.moddiscovery.ModInfo; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.loading.moddiscovery.ModInfo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.spongepowered.common.launch.Launch; @@ -46,6 +46,7 @@ public class ForgePluginContainer implements PluginContainer { private Logger logger; private PluginMetadata pluginMetadata; + private Object instance; // Find a way to get the instance of a plugin/mod from NeoForge ForgePluginContainer(final ModContainer modContainer) { this.modContainer = modContainer; @@ -75,7 +76,7 @@ public Logger logger() { public Optional locateResource(URI relative) { Objects.requireNonNull(relative, "relative"); - final ClassLoader classLoader = this.modContainer.getMod().getClass().getClassLoader(); + final ClassLoader classLoader = this.modContainer.getClass().getClassLoader(); final URL resolved = classLoader.getResource(relative.getPath()); try { if (resolved == null) { @@ -89,7 +90,7 @@ public Optional locateResource(URI relative) { @Override public Object instance() { - return this.modContainer.getMod(); + return instance; } private static final Map containers = new MapMaker().weakKeys().makeMap(); diff --git a/forge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginManager.java b/forge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginManager.java index 074f2e0992e..0c571c66c94 100644 --- a/forge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginManager.java +++ b/forge/src/launch/java/org/spongepowered/forge/launch/plugin/ForgePluginManager.java @@ -26,9 +26,11 @@ import com.google.common.collect.ImmutableList; import com.google.inject.Singleton; -import net.minecraftforge.fml.ModList; +import net.neoforged.fml.ModList; +import net.neoforged.fml.common.Mod; import org.spongepowered.common.launch.plugin.SpongePluginManager; import org.spongepowered.plugin.PluginContainer; +import org.spongepowered.plugin.builtin.jvm.Plugin; import java.util.Collection; import java.util.Objects; @@ -40,7 +42,10 @@ public final class ForgePluginManager implements SpongePluginManager { @Override public Optional fromInstance(final Object instance) { - return ModList.get().getModContainerByObject(Objects.requireNonNull(instance, "instance")).map(ForgePluginContainer::of); + Objects.requireNonNull(instance, "instance"); + if(instance.getClass().isAnnotationPresent(Plugin.class)) return plugin(instance.getClass().getAnnotation(Plugin.class).value()); + if(instance.getClass().isAnnotationPresent(Mod.class)) return plugin(instance.getClass().getAnnotation(Mod.class).value()); + return Optional.empty(); } @Override diff --git a/forge/src/main/java/org/spongepowered/forge/SpongeAPIMod.java b/forge/src/main/java/org/spongepowered/forge/SpongeAPIMod.java index 863a0654753..dbfdcc9ea0b 100644 --- a/forge/src/main/java/org/spongepowered/forge/SpongeAPIMod.java +++ b/forge/src/main/java/org/spongepowered/forge/SpongeAPIMod.java @@ -24,7 +24,7 @@ */ package org.spongepowered.forge; -import net.minecraftforge.fml.common.Mod; +import net.neoforged.fml.common.Mod; @Mod("spongeapi") public class SpongeAPIMod { diff --git a/forge/src/main/java/org/spongepowered/forge/SpongeForgeMod.java b/forge/src/main/java/org/spongepowered/forge/SpongeForgeMod.java index 200740664e5..a1e2ba478c9 100644 --- a/forge/src/main/java/org/spongepowered/forge/SpongeForgeMod.java +++ b/forge/src/main/java/org/spongepowered/forge/SpongeForgeMod.java @@ -25,21 +25,20 @@ package org.spongepowered.forge; import net.minecraft.client.Minecraft; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MobCategory; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.EntityAttributeCreationEvent; -import net.minecraftforge.event.server.ServerAboutToStartEvent; -import net.minecraftforge.event.server.ServerStartedEvent; -import net.minecraftforge.event.server.ServerStoppingEvent; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; -import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegisterEvent; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.entity.EntityAttributeCreationEvent; +import net.neoforged.neoforge.event.server.ServerAboutToStartEvent; +import net.neoforged.neoforge.event.server.ServerStartedEvent; +import net.neoforged.neoforge.event.server.ServerStoppingEvent; +import net.neoforged.neoforge.registries.RegisterEvent; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.spongepowered.api.Client; @@ -53,21 +52,17 @@ import org.spongepowered.common.launch.Lifecycle; import org.spongepowered.common.network.channel.SpongeChannelManager; import org.spongepowered.common.network.packet.SpongePacketHandler; -import org.spongepowered.forge.hook.ForgeChannelHooks; -import org.spongepowered.forge.hook.ForgeEventHooks; -import org.spongepowered.forge.hook.ForgeGeneralHooks; -import org.spongepowered.forge.hook.ForgeItemHooks; -import org.spongepowered.forge.hook.ForgeWorldHooks; +import org.spongepowered.forge.hook.*; -@Mod("spongeforge") +@Mod("spongeneoforge") public final class SpongeForgeMod { - private final Logger logger = LogManager.getLogger("spongeforge"); + private final Logger logger = LogManager.getLogger("SpongeNeoForge"); public SpongeForgeMod() { // WorldPersistenceHooks.addHook(SpongeLevelDataPersistence.INSTANCE); // TODO SF 1.19.4 - final IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus(); + final IEventBus modBus = NeoForge.EVENT_BUS; // modBus: add all FML events with it modBus.addListener(this::onCommonSetup); @@ -76,7 +71,7 @@ public SpongeForgeMod() { modBus.addListener(this::onEntityAttributeCreationEvent); // annotation events, for non-FML things - MinecraftForge.EVENT_BUS.register(this); + modBus.register(this); // Set platform hooks as required PlatformHooks.INSTANCE.setEventHooks(new ForgeEventHooks()); @@ -138,7 +133,7 @@ public void onServerStoppingEvent(final ServerStoppingEvent event) { } public void onRegister(RegisterEvent event) { - if (event.getRegistryKey() == ForgeRegistries.Keys.ENTITY_TYPES) { + if (event.getRegistryKey() == BuiltInRegistries.ENTITY_TYPE) { SpongeEntityTypes.HUMAN = EntityType.Builder.of(HumanEntity::new, MobCategory.MISC) .noSave() .sized(0.6F, 1.8F) @@ -147,7 +142,7 @@ public void onRegister(RegisterEvent event) { .build("sponge:human") ; - event.register(ForgeRegistries.Keys.ENTITY_TYPES, helper -> helper.register(HumanEntity.KEY, SpongeEntityTypes.HUMAN)); + event.register(BuiltInRegistries.ENTITY_TYPE.key(), helper -> helper.register(HumanEntity.KEY, SpongeEntityTypes.HUMAN)); } } public void onEntityAttributeCreationEvent(final EntityAttributeCreationEvent event) { diff --git a/forge/src/main/java/org/spongepowered/forge/SpongeMod.java b/forge/src/main/java/org/spongepowered/forge/SpongeMod.java index 3785f28e1e5..b6524043c06 100644 --- a/forge/src/main/java/org/spongepowered/forge/SpongeMod.java +++ b/forge/src/main/java/org/spongepowered/forge/SpongeMod.java @@ -24,7 +24,7 @@ */ package org.spongepowered.forge; -import net.minecraftforge.fml.common.Mod; +import net.neoforged.fml.common.Mod; @Mod("sponge") public class SpongeMod { diff --git a/forge/src/main/java/org/spongepowered/forge/hook/ForgeChannelHooks.java b/forge/src/main/java/org/spongepowered/forge/hook/ForgeChannelHooks.java index 8f5b2ace635..82e03a96b29 100644 --- a/forge/src/main/java/org/spongepowered/forge/hook/ForgeChannelHooks.java +++ b/forge/src/main/java/org/spongepowered/forge/hook/ForgeChannelHooks.java @@ -24,13 +24,14 @@ */ package org.spongepowered.forge.hook; +import io.netty.buffer.Unpooled; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket; import net.minecraft.network.protocol.common.ServerboundCustomPayloadPacket; import net.minecraft.network.protocol.common.custom.CustomPacketPayload; import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.network.ForgePayload; + import org.spongepowered.api.network.EngineConnectionSide; import org.spongepowered.api.network.channel.ChannelBuf; import org.spongepowered.common.hooks.ChannelHooks; @@ -48,9 +49,9 @@ public void registerPlatformChannels(final Consumer createRegisterPayload(final ChannelBuf payload, final EngineConnectionSide side) { if (side == EngineConnectionSide.CLIENT) { - return new ServerboundCustomPayloadPacket(new ForgePayload((ResourceLocation) (Object) Constants.Channels.REGISTER_KEY, null, b -> b.writeBytes((FriendlyByteBuf) payload))); + return ServerboundCustomPayloadPacket.CONFIG_STREAM_CODEC.decode(new FriendlyByteBuf(Unpooled.buffer()).writeResourceLocation((ResourceLocation) (Object) Constants.Channels.REGISTER_KEY).writeBytes(payload.array())); } else if (side == EngineConnectionSide.SERVER) { - return new ClientboundCustomPayloadPacket(new ForgePayload((ResourceLocation) (Object) Constants.Channels.REGISTER_KEY, null, b -> b.writeBytes((FriendlyByteBuf) payload))); + return ClientboundCustomPayloadPacket.CONFIG_STREAM_CODEC.decode(new FriendlyByteBuf(Unpooled.buffer()).writeResourceLocation((ResourceLocation) (Object) Constants.Channels.REGISTER_KEY).writeBytes(payload.array())); } else { throw new UnsupportedOperationException(); } diff --git a/forge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java b/forge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java index cb304532d82..681007ddbe2 100644 --- a/forge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java +++ b/forge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java @@ -27,10 +27,8 @@ import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraftforge.common.ForgeHooks; -import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.event.entity.player.CriticalHitEvent; +import net.minecraft.world.item.ItemStack;; +import net.neoforged.neoforge.event.entity.player.CriticalHitEvent; import org.spongepowered.common.hooks.EventHooks; @SuppressWarnings("UnstableApiUsage") @@ -49,7 +47,7 @@ public CriticalHitResult callCriticalHitEvent( ) { final CriticalHitEvent hitResult = ForgeHooks.getCriticalHit(player, targetEntity, isCriticalAttack, v + 1.0F); if (hitResult != null) { - return new CriticalHitResult(true, hitResult.getDamageModifier() - 1.0F); + return new CriticalHitResult(true, hitResult.getDamageMultiplier() - 1.0F); } return new CriticalHitResult(false, v); } diff --git a/forge/src/main/java/org/spongepowered/forge/hook/ForgeGeneralHooks.java b/forge/src/main/java/org/spongepowered/forge/hook/ForgeGeneralHooks.java index 8307f66555a..b5e184f002a 100644 --- a/forge/src/main/java/org/spongepowered/forge/hook/ForgeGeneralHooks.java +++ b/forge/src/main/java/org/spongepowered/forge/hook/ForgeGeneralHooks.java @@ -26,6 +26,7 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.status.ServerStatus; + import org.spongepowered.common.hooks.GeneralHooks; import java.util.Optional; @@ -33,6 +34,6 @@ public class ForgeGeneralHooks implements GeneralHooks { public ServerStatus createServerStatus(ServerStatus originalStatus, Component description, Optional players, Optional version, Optional favicon) { - return new ServerStatus(description, players, version, favicon, originalStatus.enforcesSecureChat(), originalStatus.forgeData()); + return new ServerStatus(description, players, version, favicon, originalStatus.enforcesSecureChat(), originalStatus.isModded()); } } diff --git a/forge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java b/forge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java index 7bb6d65098e..6da70fbb6e7 100644 --- a/forge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java +++ b/forge/src/main/java/org/spongepowered/forge/hook/ForgeWorldHooks.java @@ -30,8 +30,10 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.level.LevelEvent; + +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.event.level.LevelEvent; + import org.spongepowered.common.hooks.WorldHooks; public class ForgeWorldHooks implements WorldHooks { @@ -59,6 +61,6 @@ public boolean isRestoringBlocks(final Level world) { @Override public void postLoadWorld(final ServerLevel world) { - MinecraftForge.EVENT_BUS.post(new LevelEvent.Load(world)); + NeoForge.EVENT_BUS.post(new LevelEvent.Load(world)); } } diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/MinecraftForgeMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/MinecraftForgeMixin_Forge.java index 1f23d293092..536ca09e693 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/MinecraftForgeMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/MinecraftForgeMixin_Forge.java @@ -24,21 +24,21 @@ */ package org.spongepowered.forge.mixin.core.minecraftforge; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.BusBuilderImpl; -import net.minecraftforge.eventbus.api.BusBuilder; -import net.minecraftforge.eventbus.api.IEventBus; +import net.neoforged.bus.BusBuilderImpl; +import net.neoforged.bus.api.BusBuilder; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.common.NeoForge; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.forge.launch.event.ForgeEventManager; import org.spongepowered.forge.launch.event.SpongeEventBus; -@Mixin(MinecraftForge.class) +@Mixin(NeoForge.class) public abstract class MinecraftForgeMixin_Forge { @Redirect(method = "", at = @At(value = "INVOKE", - target = "Lnet/minecraftforge/eventbus/api/BusBuilder;build()Lnet/minecraftforge/eventbus/api/IEventBus;", remap = false)) + target = "Lnet/neoforged/bus/api/BusBuilder;build()Lnet/neoforged/bus/api/IEventBus;", remap = false)) private static IEventBus forge$substituteForgeEventBus(final BusBuilder builder) { return new ForgeEventManager(new SpongeEventBus((BusBuilderImpl) builder)); } diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin_Forge.java index ebff4495789..fa068009ebe 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/world/level/block/entity/AbstractFurnaceBlockEntityMixin_Forge.java @@ -57,13 +57,12 @@ import org.spongepowered.common.inventory.adapter.impl.slots.SlotAdapter; import org.spongepowered.common.item.util.ItemStackUtil; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Optional; -import javax.annotation.Nullable; - @Mixin(AbstractFurnaceBlockEntity.class) public abstract class AbstractFurnaceBlockEntityMixin_Forge implements AbstractFurnaceBlockEntityBridge { From b3a5201611a44902720097ea3a3586270949ff70 Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Wed, 21 Aug 2024 17:04:34 +0700 Subject: [PATCH 05/13] Enable NeoForge module --- spongeneoforge.settings.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spongeneoforge.settings.gradle.kts b/spongeneoforge.settings.gradle.kts index 28d34f5baeb..47955515f69 100644 --- a/spongeneoforge.settings.gradle.kts +++ b/spongeneoforge.settings.gradle.kts @@ -1,4 +1,4 @@ // Uncomment to enable SpongeForge module. // By default only Sponge and SpongeVanilla are made available -//include(":SpongeNeoForge") -//project(":SpongeNeoForge").projectDir = file("neoforge") +include(":SpongeNeoForge") +project(":SpongeNeoForge").projectDir = file("forge") From f0b9da5c717fb40a29fbecc70b551a3386c11033 Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Wed, 21 Aug 2024 17:04:39 +0700 Subject: [PATCH 06/13] Update verification-metadata.xml --- gradle/verification-metadata.xml | 130 ++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index 1f7d1675712..4da99591ddd 100755 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -571,6 +571,14 @@
+ + + + + + + + @@ -667,6 +675,11 @@ + + + + + @@ -760,6 +773,14 @@ + + + + + + + + @@ -811,6 +832,11 @@ + + + + + @@ -883,6 +909,14 @@ + + + + + + + + @@ -1308,6 +1342,14 @@ + + + + + + + + @@ -2505,6 +2547,14 @@ + + + + + + + + @@ -3155,6 +3205,14 @@ + + + + + + + + @@ -3187,6 +3245,14 @@ + + + + + + + + @@ -3207,6 +3273,9 @@ + + + @@ -3233,6 +3302,14 @@ + + + + + + + + @@ -3259,12 +3336,22 @@ - + + + + + + + + + + + @@ -3425,6 +3512,11 @@ + + + + + @@ -3523,6 +3615,11 @@ + + + + + @@ -4174,6 +4271,14 @@ + + + + + + + + @@ -4252,6 +4357,11 @@ + + + + + @@ -4262,6 +4372,24 @@ + + + + + + + + + + + + + + + + + + From edda62e5bc295ba6777cc022db982f6be8de9358 Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Wed, 21 Aug 2024 17:07:03 +0700 Subject: [PATCH 07/13] Update PluginModContainer class --- .../launch/plugin/PluginModContainer.java | 78 ++++++++----------- 1 file changed, 31 insertions(+), 47 deletions(-) diff --git a/forge/src/launch/java/org/spongepowered/forge/launch/plugin/PluginModContainer.java b/forge/src/launch/java/org/spongepowered/forge/launch/plugin/PluginModContainer.java index 73f92ca0389..807600dba94 100644 --- a/forge/src/launch/java/org/spongepowered/forge/launch/plugin/PluginModContainer.java +++ b/forge/src/launch/java/org/spongepowered/forge/launch/plugin/PluginModContainer.java @@ -25,20 +25,20 @@ package org.spongepowered.forge.launch.plugin; import com.google.inject.Injector; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.EventBusErrorMessage; -import net.minecraftforge.eventbus.api.BusBuilder; -import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.eventbus.api.IEventListener; -import net.minecraftforge.fml.Logging; -import net.minecraftforge.fml.ModContainer; -import net.minecraftforge.fml.ModLoadingException; -import net.minecraftforge.fml.ModLoadingStage; -import net.minecraftforge.fml.event.IModBusEvent; -import net.minecraftforge.fml.javafmlmod.AutomaticEventSubscriber; -import net.minecraftforge.forgespi.language.IModInfo; -import net.minecraftforge.forgespi.language.ModFileScanData; +import net.neoforged.bus.EventBusErrorMessage; +import net.neoforged.bus.api.BusBuilder; +import net.neoforged.bus.api.Event; +import net.neoforged.bus.api.EventListener; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.fml.Logging; +import net.neoforged.fml.ModContainer; +import net.neoforged.fml.ModLoadingException; +import net.neoforged.fml.ModLoadingIssue; +import net.neoforged.fml.event.IModBusEvent; +import net.neoforged.fml.javafmlmod.AutomaticEventSubscriber; +import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforgespi.language.IModInfo; +import net.neoforged.neoforgespi.language.ModFileScanData; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.spongepowered.common.inject.plugin.PluginModule; @@ -46,8 +46,6 @@ import org.spongepowered.forge.launch.event.ForgeEventManager; import org.spongepowered.plugin.PluginContainer; -import java.util.Optional; - // Spongified FMLModContainer public final class PluginModContainer extends ModContainer { private static final Logger LOGGER = LogManager.getLogger(); @@ -56,30 +54,33 @@ public final class PluginModContainer extends ModContainer { private final IEventBus eventBus; private Object modInstance; private final Class modClass; + private final Module layer; public PluginModContainer(IModInfo info, String className, ModFileScanData modFileScanResults, ModuleLayer gameLayer) { super(info); LOGGER.debug(Logging.LOADING, "Creating PluginModContainer instance for {}", className); this.scanResults = modFileScanResults; - this.activityMap.put(ModLoadingStage.CONSTRUCT, this::constructPlugin); - this.eventBus = BusBuilder.builder().setExceptionHandler(this::onEventFailed).setTrackPhases(false).markerType(IModBusEvent.class).useModLauncher().build(); - this.configHandler = Optional.of(ce -> this.eventBus.post(ce.self())); - this.contextExtension = () -> null; + this.eventBus = BusBuilder.builder().setExceptionHandler(this::onEventFailed).markerType(IModBusEvent.class).build(); + this.layer = gameLayer.findModule(info.getOwningFile().moduleName()).orElseThrow(); try { - Module module = gameLayer.findModule(info.getOwningFile().moduleName()).orElseThrow(); - modClass = Class.forName(module, className); + modClass = Class.forName(this.layer, className); LOGGER.trace(Logging.LOADING, "Loaded modclass {} with {}", modClass.getName(), modClass.getClassLoader()); } catch (Throwable e) { LOGGER.error(Logging.LOADING, "Failed to load class {}", className, e); - throw new ModLoadingException(info, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadmodclass", e); + throw new ModLoadingException(ModLoadingIssue.error("fml.modloadingissue.failedtoloadmodclass").withCause(e).withAffectedMod(info)); } } - private void onEventFailed(IEventBus iEventBus, Event event, IEventListener[] iEventListeners, int i, Throwable throwable) { + private void onEventFailed(IEventBus iEventBus, Event event, EventListener[] iEventListeners, int i, Throwable throwable) { LOGGER.error(new EventBusErrorMessage(event, i, iEventListeners, throwable)); } + @Override + protected void constructMod() { + this.constructPlugin(); + } + private void constructPlugin() { try { LOGGER.trace(Logging.LOADING, "Loading plugin instance {} of type {}", getModId(), this.modClass.getName()); @@ -87,43 +88,26 @@ private void constructPlugin() { final PluginContainer pluginContainer = ForgePluginContainer.of(this); final Injector childInjector = Launch.instance().lifecycle().platformInjector().createChildInjector(new PluginModule(pluginContainer, this.modClass)); this.modInstance = childInjector.getInstance(this.modClass); - ((ForgeEventManager) MinecraftForge.EVENT_BUS).registerListeners(pluginContainer, this.modInstance); + ((ForgeEventManager) NeoForge.EVENT_BUS).registerListeners(pluginContainer, this.modInstance); LOGGER.trace(Logging.LOADING, "Loaded plugin instance {} of type {}", getModId(), this.modClass.getName()); } catch (Throwable e) { LOGGER.error(Logging.LOADING, "Failed to create plugin instance. PluginID: {}, class {}", getModId(), this.modClass.getName(), e); - throw new ModLoadingException(this.modInfo, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadmod", e, this.modClass); + throw new ModLoadingException(ModLoadingIssue.error("fml.modloadingissue.failedtoloadmod").withCause(e).withAffectedMod(modInfo)); } try { LOGGER.trace(Logging.LOADING, "Injecting Automatic event subscribers for {}", getModId()); - AutomaticEventSubscriber.inject(this, this.scanResults, this.modClass.getClassLoader()); + AutomaticEventSubscriber.inject(this, this.scanResults, this.layer); LOGGER.trace(Logging.LOADING, "Completed Automatic event subscribers for {}", getModId()); } catch (Throwable e) { LOGGER.error(Logging.LOADING, "Failed to register automatic subscribers. PluginID: {}, class {}", getModId(), this.modClass.getName(), e); - throw new ModLoadingException(this.modInfo, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadmod", e, this.modClass); + throw new ModLoadingException(ModLoadingIssue.error("fml.modloadingissue.failedtoloadmod").withCause(e).withAffectedMod(modInfo)); } } @Override - public boolean matches(Object mod) { - return mod == this.modInstance; - } - - @Override - public Object getMod() { - return this.modInstance; - } - - @Override - protected void acceptEvent(final T e) { - try { - LOGGER.trace(Logging.LOADING, "Firing event for modid {} : {}", this.getModId(), e); - this.eventBus.post(e); - LOGGER.trace(Logging.LOADING, "Fired event for modid {} : {}", this.getModId(), e); - } catch (Throwable t) { - LOGGER.error(Logging.LOADING, "Caught exception during event {} dispatch for modid {}", e, this.getModId(), t); - throw new ModLoadingException(this.modInfo, this.modLoadingStage, "fml.modloading.errorduringevent", t); - } + public IEventBus getEventBus() { + return this.eventBus; } } From 9c0c0335b5be23a39f78044108042421b705c53a Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Wed, 21 Aug 2024 17:36:06 +0700 Subject: [PATCH 08/13] Update Events --- .../spongepowered/forge/hook/ForgeEventHooks.java | 12 +++++------- .../event/block/ChangeBlockEvent_AllMixin_Forge.java | 4 ++-- .../ChangeEntityWorldEvent_PreMixin_Forge.java | 4 ++-- .../ChangeEventWorldEvent_PostMixin_Forge.java | 4 ++-- .../EntityTravelToDimensionEventMixin_Forge.java | 8 ++++---- ...Event_PlayerChangedDimensionEventMixin_Forge.java | 2 +- .../event/world/BlockEventMixin_Forge.java | 2 +- .../world/BlockEvent_BreakEventMixin_Forge.java | 6 +++--- 8 files changed, 20 insertions(+), 22 deletions(-) diff --git a/forge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java b/forge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java index 681007ddbe2..003269199d8 100644 --- a/forge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java +++ b/forge/src/main/java/org/spongepowered/forge/hook/ForgeEventHooks.java @@ -27,7 +27,8 @@ import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack;; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.common.CommonHooks; import net.neoforged.neoforge.event.entity.player.CriticalHitEvent; import org.spongepowered.common.hooks.EventHooks; @@ -38,17 +39,14 @@ public final class ForgeEventHooks implements EventHooks { public void callItemDestroyedEvent( final Player player, final ItemStack stack, final InteractionHand hand ) { - ForgeEventFactory.onPlayerDestroyItem(player, stack, InteractionHand.MAIN_HAND); + net.neoforged.neoforge.event.EventHooks.onPlayerDestroyItem(player, stack, InteractionHand.MAIN_HAND); } @Override public CriticalHitResult callCriticalHitEvent( final Player player, final Entity targetEntity, final boolean isCriticalAttack, final float v ) { - final CriticalHitEvent hitResult = ForgeHooks.getCriticalHit(player, targetEntity, isCriticalAttack, v + 1.0F); - if (hitResult != null) { - return new CriticalHitResult(true, hitResult.getDamageMultiplier() - 1.0F); - } - return new CriticalHitResult(false, v); + final CriticalHitEvent hitResult = CommonHooks.fireCriticalHit(player, targetEntity, isCriticalAttack, v + 1.0F); + return new CriticalHitResult(hitResult.isCriticalHit(), hitResult.getDamageMultiplier() - 1.0F); } } diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/block/ChangeBlockEvent_AllMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/block/ChangeBlockEvent_AllMixin_Forge.java index d9ad83e55f4..0f5d74b2181 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/block/ChangeBlockEvent_AllMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/block/ChangeBlockEvent_AllMixin_Forge.java @@ -27,8 +27,8 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.event.level.BlockEvent; -import net.minecraftforge.eventbus.api.Event; +import net.neoforged.bus.api.Event; +import net.neoforged.neoforge.event.level.BlockEvent; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.block.transaction.BlockTransaction; import org.spongepowered.api.block.transaction.Operation; diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEntityWorldEvent_PreMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEntityWorldEvent_PreMixin_Forge.java index 30a236eefe4..2b42a80c563 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEntityWorldEvent_PreMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEntityWorldEvent_PreMixin_Forge.java @@ -26,8 +26,8 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; -import net.minecraftforge.event.entity.EntityTravelToDimensionEvent; -import net.minecraftforge.eventbus.api.Event; +import net.neoforged.bus.api.Event; +import net.neoforged.neoforge.event.entity.EntityTravelToDimensionEvent; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.event.entity.ChangeEntityWorldEvent; import org.spongepowered.asm.mixin.Mixin; diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEventWorldEvent_PostMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEventWorldEvent_PostMixin_Forge.java index f85995d0727..5fcebabc2a9 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEventWorldEvent_PostMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/api/event/entity/ChangeEventWorldEvent_PostMixin_Forge.java @@ -26,8 +26,8 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.eventbus.api.Event; +import net.neoforged.bus.api.Event; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.event.entity.ChangeEntityWorldEvent; import org.spongepowered.asm.mixin.Mixin; diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/EntityTravelToDimensionEventMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/EntityTravelToDimensionEventMixin_Forge.java index bb964ccbbfe..29b5b8acf58 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/EntityTravelToDimensionEventMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/EntityTravelToDimensionEventMixin_Forge.java @@ -28,8 +28,8 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; -import net.minecraftforge.event.entity.EntityEvent; -import net.minecraftforge.event.entity.EntityTravelToDimensionEvent; +import net.neoforged.neoforge.event.entity.EntityEvent; +import net.neoforged.neoforge.event.entity.EntityTravelToDimensionEvent; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.event.Event; import org.spongepowered.api.event.SpongeEventFactory; @@ -52,7 +52,7 @@ public abstract class EntityTravelToDimensionEventMixin_Forge implements ForgeEv @Override public void bridge$syncFrom(final Event event) { if (event instanceof ChangeEntityWorldEvent.Pre) { - ((net.minecraftforge.eventbus.api.Event) (Object) this).setCanceled(((ChangeEntityWorldEvent.Pre) event).isCancelled()); + ((EntityTravelToDimensionEvent) (Object) this).setCanceled(((ChangeEntityWorldEvent.Pre) event).isCancelled()); this.dimension = ((ServerLevel) ((ChangeEntityWorldEvent.Pre) event).destinationWorld()).dimension(); } } @@ -60,7 +60,7 @@ public abstract class EntityTravelToDimensionEventMixin_Forge implements ForgeEv @Override public void bridge$syncTo(final Event event) { if (event instanceof ChangeEntityWorldEvent.Pre) { - ((ChangeEntityWorldEvent.Pre) event).setCancelled(((net.minecraftforge.eventbus.api.Event) (Object) this).isCanceled()); + ((ChangeEntityWorldEvent.Pre) event).setCancelled(((EntityTravelToDimensionEvent) (Object) this).isCanceled()); } } diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/player/PlayerEvent_PlayerChangedDimensionEventMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/player/PlayerEvent_PlayerChangedDimensionEventMixin_Forge.java index f7490394fde..54df86a54be 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/player/PlayerEvent_PlayerChangedDimensionEventMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/entity/player/PlayerEvent_PlayerChangedDimensionEventMixin_Forge.java @@ -26,7 +26,7 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.Level; -import net.minecraftforge.event.entity.player.PlayerEvent; +import net.neoforged.neoforge.event.entity.player.PlayerEvent; import org.spongepowered.api.entity.Entity; import org.spongepowered.api.event.Event; import org.spongepowered.api.event.SpongeEventFactory; diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEventMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEventMixin_Forge.java index 166b9201a39..4b435265efb 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEventMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEventMixin_Forge.java @@ -27,7 +27,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.event.level.BlockEvent; +import net.neoforged.neoforge.event.level.BlockEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEvent_BreakEventMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEvent_BreakEventMixin_Forge.java index 55845d3e685..34f2abf99c5 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEvent_BreakEventMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/event/world/BlockEvent_BreakEventMixin_Forge.java @@ -25,7 +25,7 @@ package org.spongepowered.forge.mixin.core.minecraftforge.event.world; import net.minecraft.world.level.LevelAccessor; -import net.minecraftforge.event.level.BlockEvent; +import net.neoforged.neoforge.event.level.BlockEvent; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.api.block.BlockState; import org.spongepowered.api.block.BlockTypes; @@ -57,14 +57,14 @@ public abstract class BlockEvent_BreakEventMixin_Forge extends BlockEventMixin_F .stream() .filter(x -> x.original().position().equals(pos)) .anyMatch(x -> !x.isValid() || x.operation() != Operations.BREAK.get() || x.custom().isPresent())) { - ((net.minecraftforge.eventbus.api.Event) (Object) this).setCanceled(true); + ((BlockEvent.BreakEvent) (Object) this).setCanceled(true); } } } @Override public void bridge$syncTo(final Event event) { - if (event instanceof ChangeBlockEvent.All && ((net.minecraftforge.eventbus.api.Event) (Object) this).isCanceled()) { + if (event instanceof ChangeBlockEvent.All && ((BlockEvent.BreakEvent) (Object) this).isCanceled()) { final Vector3i pos = VecHelper.toVector3i(this.shadow$getPos()); ((ChangeBlockEvent.All) event).transactions(Operations.BREAK.get()).filter(x -> x.original().position().equals(pos)) .forEach(x -> x.setValid(false)); From 45a3398055670c4f421bf9ef0f6c09ca93e2975b Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Wed, 21 Aug 2024 19:17:01 +0700 Subject: [PATCH 09/13] Update BrandingControl --- .../minecraftforge/internal/BrandingControlMixin_Forge.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/internal/BrandingControlMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/internal/BrandingControlMixin_Forge.java index 841f6ba78ea..7333f3437d1 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/internal/BrandingControlMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/internal/BrandingControlMixin_Forge.java @@ -24,7 +24,7 @@ */ package org.spongepowered.forge.mixin.core.minecraftforge.internal; -import net.minecraftforge.internal.BrandingControl; +import net.neoforged.neoforge.internal.BrandingControl; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; From ecf068634b0e5e89399fcc55f23323bbe12603ec Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Wed, 21 Aug 2024 20:15:17 +0700 Subject: [PATCH 10/13] TODO Update registries --- .../registries/ForgeRegistryMixin_Forge.java | 13 ++++++++----- .../registries/RegistryManagerMixin_Forge.java | 12 ++++++------ 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/ForgeRegistryMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/ForgeRegistryMixin_Forge.java index d382d4bd688..5f9b36b560f 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/ForgeRegistryMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/ForgeRegistryMixin_Forge.java @@ -25,10 +25,9 @@ package org.spongepowered.forge.mixin.core.minecraftforge.registries; import com.google.common.collect.Maps; +import net.minecraft.core.MappedRegistry; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.registries.ForgeRegistry; -import net.minecraftforge.registries.IForgeRegistry; import org.spongepowered.api.ResourceKey; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -45,7 +44,11 @@ import java.util.Map; import java.util.StringJoiner; -@Mixin(ForgeRegistry.class) +// TODO +// IForgeRegistry -> IRegistryExtension +// ForgeRegistry -> BaseMappedRegistry, также имеет некоторую реализацию в ванильном MappedRegistry +// Хрен пойми, нужен ли этот миксин вообще. Я так и не смог понять, на что заменили SlaveMap (и заменили ли вообще) +@Mixin(MappedRegistry.class)//@Mixin(ForgeRegistry.class) public abstract class ForgeRegistryMixin_Forge { // @formatter:off @@ -55,7 +58,7 @@ public abstract class ForgeRegistryMixin_Forge { private final Map> forge$parents = Maps.newHashMap(); private boolean forge$warnedIfNoParent; - @Inject(method = "add(ILnet/minecraft/resources/ResourceLocation;Ljava/lang/Object;Ljava/lang/String;)I", at = @At("TAIL")) + /*@Inject(method = "add(ILnet/minecraft/resources/ResourceLocation;Ljava/lang/Object;Ljava/lang/String;)I", at = @At("TAIL")) public void forge$writeToParent(final int id, final ResourceLocation key, final V value, final String owner, final CallbackInfoReturnable cir) { final ResourceKey root = (ResourceKey) (Object) this.key.registry(); final ResourceKey location = (ResourceKey) (Object) this.key.location(); @@ -83,6 +86,6 @@ public abstract class ForgeRegistryMixin_Forge { if (obj instanceof RegistryBridge) { this.forge$parents.put((ResourceKey) (Object) key.name(), (RegistryBridge) obj); } - } + }*/ } diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/RegistryManagerMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/RegistryManagerMixin_Forge.java index f591b0f1463..b5d1bd817d0 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/RegistryManagerMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/minecraftforge/registries/RegistryManagerMixin_Forge.java @@ -25,8 +25,8 @@ package org.spongepowered.forge.mixin.core.minecraftforge.registries; import net.minecraft.resources.ResourceLocation; -import net.minecraftforge.registries.ForgeRegistry; -import net.minecraftforge.registries.RegistryManager; +import net.neoforged.neoforge.registries.RegistryManager; +import net.neoforged.neoforge.registries.RegistrySnapshot; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -39,13 +39,13 @@ public class RegistryManagerMixin_Forge { @SuppressWarnings("UnstableApiUsage") @Inject(method = "takeSnapshot", at = @At("RETURN")) - public void forge$dontSendSpongeDataToClient(boolean savingToDisc, CallbackInfoReturnable> cir) { - if (savingToDisc) { + public void forge$dontSendSpongeDataToClient(RegistryManager.SnapshotType snapshotType, CallbackInfoReturnable> cir) { + if (snapshotType == RegistryManager.SnapshotType.FULL) { return; } - for (ForgeRegistry.Snapshot snapshot : cir.getReturnValue().values()) { - snapshot.ids.keySet().removeIf(loc -> loc.getNamespace().equals("sponge")); + for (RegistrySnapshot snapshot : cir.getReturnValue().values()) { + snapshot.getIds().values().removeIf(loc -> loc.getNamespace().equals("sponge")); } } } From cb86afab9434349136c4d18b646d50de25e240da Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Wed, 21 Aug 2024 20:18:39 +0700 Subject: [PATCH 11/13] TODO Update forge Attack impl --- .../core/world/entity/LivingEntityMixin_Forge.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge.java index 819262550c7..64bcc4351c9 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/world/entity/LivingEntityMixin_Forge.java @@ -26,7 +26,8 @@ import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.LivingEntity; -import net.minecraftforge.common.ForgeHooks; +import net.neoforged.neoforge.common.CommonHooks; +import net.neoforged.neoforge.common.damagesource.DamageContainer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -49,16 +50,18 @@ public abstract class LivingEntityMixin_Forge implements PlatformLivingEntityBri @Override public boolean bridge$onLivingAttack(final LivingEntity entity, final DamageSource source, final float amount) { - return ForgeHooks.onLivingAttack(entity, source, amount); + return CommonHooks.onEntityIncomingDamage(entity, new DamageContainer(source, amount)); } @Override public float bridge$applyModDamage(final LivingEntity entity, final DamageSource source, final float damage) { - return ForgeHooks.onLivingHurt(entity, source, damage); + return CommonHooks.onLivingDamagePre(entity, new DamageContainer(source, damage)); } @Override public float bridge$applyModDamageBeforeFunctions(final LivingEntity entity, final DamageSource source, final float damage) { - return ForgeHooks.onLivingDamage(entity, source, damage); + // TODO This was + // return ForgeHooks.onLivingDamage(entity, source, damage); + return damage; } } From 55a79b7830d727a611440dcc84aa4e5768000a5e Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Wed, 21 Aug 2024 19:16:49 +0700 Subject: [PATCH 12/13] Update commands --- .../mixin/core/commands/CommandsMixin_Forge.java | 11 +++++------ .../commands/SpreadPlayersCommandMixin_Forge.java | 8 ++++---- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/commands/CommandsMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/commands/CommandsMixin_Forge.java index 94dbf3edd68..15fc4eb52d8 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/commands/CommandsMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/commands/CommandsMixin_Forge.java @@ -31,9 +31,8 @@ import net.minecraft.commands.Commands; import net.minecraft.commands.SharedSuggestionProvider; import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.server.command.CommandHelper; +import net.neoforged.neoforge.event.CommandEvent; +import net.neoforged.neoforge.server.command.CommandHelper; import org.spongepowered.api.command.CommandCause; import org.spongepowered.api.event.CauseStackManager; import org.spongepowered.api.event.EventContextKeys; @@ -59,8 +58,8 @@ public abstract class CommandsMixin_Forge { // The event fired by Forge is fired in SpongeForgeCommandManager at the appropriate time. @Redirect(method = "performCommand", - at = @At(value = "INVOKE", target = "Lnet/minecraftforge/eventbus/api/IEventBus;post(Lnet/minecraftforge/eventbus/api/Event;)Z")) - private boolean forge$redirectToSpongeCommandManager(IEventBus instance, Event event) { + at = @At(value = "INVOKE", target = "Lnet/neoforged/neoforge/event/CommandEvent;isCanceled()Z")) + private boolean forge$redirectToSpongeCommandManager(CommandEvent event) { return false; } @@ -68,7 +67,7 @@ public abstract class CommandsMixin_Forge { @SuppressWarnings("unchecked") @Redirect(method = "sendCommands", at = @At( value = "INVOKE", - target = "Lnet/minecraftforge/server/command/CommandHelper;mergeCommandNode(Lcom/mojang/brigadier/tree/CommandNode;Lcom/mojang/brigadier/tree/CommandNode;Ljava/util/Map;Ljava/lang/Object;Lcom/mojang/brigadier/Command;Ljava/util/function/Function;)V", + target = "Lnet/neoforged/neoforge/server/command/CommandHelper;mergeCommandNode(Lcom/mojang/brigadier/tree/CommandNode;Lcom/mojang/brigadier/tree/CommandNode;Ljava/util/Map;Ljava/lang/Object;Lcom/mojang/brigadier/Command;Ljava/util/function/Function;)V", remap = false )) private void impl$addNonBrigSuggestions( diff --git a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/server/commands/SpreadPlayersCommandMixin_Forge.java b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/server/commands/SpreadPlayersCommandMixin_Forge.java index 94adf0c914b..770381f25cb 100644 --- a/forge/src/mixins/java/org/spongepowered/forge/mixin/core/server/commands/SpreadPlayersCommandMixin_Forge.java +++ b/forge/src/mixins/java/org/spongepowered/forge/mixin/core/server/commands/SpreadPlayersCommandMixin_Forge.java @@ -26,8 +26,8 @@ import net.minecraft.server.commands.SpreadPlayersCommand; import net.minecraft.world.entity.Entity; -import net.minecraftforge.event.ForgeEventFactory; -import net.minecraftforge.event.entity.EntityTeleportEvent; +import net.neoforged.neoforge.event.EventHooks; +import net.neoforged.neoforge.event.entity.EntityTeleportEvent; import org.spongepowered.api.event.CauseStackManager; import org.spongepowered.api.event.EventContextKeys; import org.spongepowered.api.event.cause.entity.MovementTypes; @@ -41,13 +41,13 @@ public abstract class SpreadPlayersCommandMixin_Forge { @Redirect(method = "setPlayerPositions", at = @At( value = "INVOKE", - target = "Lnet/minecraftforge/event/ForgeEventFactory;onEntityTeleportSpreadPlayersCommand(Lnet/minecraft/world/entity/Entity;DDD)Lnet/minecraftforge/event/entity/EntityTeleportEvent$SpreadPlayersCommand;" + target = "Lnet/neoforged/neoforge/event/EventHooks;onEntityTeleportSpreadPlayersCommand(Lnet/minecraft/world/entity/Entity;DDD)Lnet/neoforged/neoforge/event/entity/EntityTeleportEvent$SpreadPlayersCommand;" )) private static EntityTeleportEvent.SpreadPlayersCommand vanilla$createCauseFrameForTeleport(Entity entity, double targetX, double targetY, double targetZ) { try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) { frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND); - return ForgeEventFactory.onEntityTeleportSpreadPlayersCommand(entity, targetX, targetY, targetZ); + return EventHooks.onEntityTeleportSpreadPlayersCommand(entity, targetX, targetY, targetZ); } } } From 120d1375780020b328b20c9b880c9c13fc46e455 Mon Sep 17 00:00:00 2001 From: MrHell228 Date: Wed, 21 Aug 2024 20:19:31 +0700 Subject: [PATCH 13/13] TODO Update bootstrap --- forge/build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts index 571443d18de..9019fd80827 100644 --- a/forge/build.gradle.kts +++ b/forge/build.gradle.kts @@ -186,6 +186,8 @@ extensions.configure(LoomGradleExtensionAPI::class) { // Arch-loom bug, skip broken union-relauncher runs.forEach { + // TODO find replacement + // net.minecraft.client.main.Main ? mcp.client.Start ? it.mainClass.set("net.minecraftforge.bootstrap.ForgeBootstrap") } }