Compare commits
35 Commits
Author | SHA1 | Date |
---|---|---|
Shadowfacts | 7e582d39ee | |
Shadowfacts | 09bd973e77 | |
NikkyAI | 85b8fd917b | |
Shadowfacts | 7aa0a3ef37 | |
Shadowfacts | 1342a6f5a6 | |
Shadowfacts | b18b818f64 | |
Shadowfacts | 90c0276180 | |
Shadowfacts | 583e9d8170 | |
Shadowfacts | 9809314759 | |
Shadowfacts | 9e8935d4cf | |
Shadowfacts | 7b885ea4cd | |
Shadowfacts | 7cebe692e7 | |
Shadowfacts | 26b895b6ce | |
gegy1000 | df437491f1 | |
Shadowfacts | ecf20f1a76 | |
Shadowfacts | 5d8ddee776 | |
Shadowfacts | c64538e7b0 | |
Kitten | be61809a7b | |
gegy1000 | 438c604d52 | |
Shadowfacts | 68c718fe57 | |
Shadowfacts | 06f171947d | |
Shadowfacts | ebba471b4b | |
Marvin Rösch | 6f718d74fc | |
Marvin Rösch | 23dfb368e1 | |
Shadowfacts | 8a5751bc19 | |
Shadowfacts | bb3a703467 | |
Severen Redwood | ae873b5cc4 | |
Shadowfacts | b3fe2d34b3 | |
Shadowfacts | 2065fbd62b | |
Shadowfacts | 33320699ac | |
Shadowfacts | 469fcdaea7 | |
Shadowfacts | d5138b9814 | |
Shadowfacts | 4dda702c93 | |
Shadowfacts | 531b3da7ef | |
Shadowfacts | e0209c61b2 |
|
@ -2,14 +2,15 @@
|
||||||
Fork of [Emberwalker's Forgelin](https://github.com/Emberwalker/Forgelin).
|
Fork of [Emberwalker's Forgelin](https://github.com/Emberwalker/Forgelin).
|
||||||
|
|
||||||
## Additions
|
## Additions
|
||||||
- Shades the Kotlin standard library, runtime, and reflect libraries so you don't have to.
|
- Shades the Kotlin standard library, runtime, coroutines-core, and reflect libraries so you don't have to.
|
||||||
- Provides a Forge `ILanguageAdapter` for using Kotlin `object` classes as your main mod class.
|
- Provides a Forge `ILanguageAdapter` for using Kotlin `object` classes as your main mod class.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
```groovy
|
```groovy
|
||||||
repositories {
|
repositories {
|
||||||
|
jcenter()
|
||||||
maven {
|
maven {
|
||||||
url "http://mvn.rx14.co.uk/shadowfacts/"
|
url "http://maven.shadowfacts.net/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,4 +19,6 @@ dependencies {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
All versions can be seen [here](http://mvn.rx14.co.uk/shadowfacts/net/shadowfacts/Forgelin/).
|
All versions can be seen [here](http://maven.shadowfacts.net/net/shadowfacts/Forgelin/).
|
||||||
|
|
||||||
|
**Note:** You must have the `jcenter()` call in your `repositories` block. JCenter is used to host the Kotlin coroutines libraries.
|
||||||
|
|
44
build.gradle
44
build.gradle
|
@ -7,7 +7,7 @@ buildscript {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath "net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT"
|
classpath "net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT"
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,9 @@ plugins {
|
||||||
id "com.github.johnrengelman.shadow" version "1.2.3"
|
id "com.github.johnrengelman.shadow" version "1.2.3"
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: "net.minecraftforge.gradle.forge"
|
|
||||||
apply plugin: "kotlin"
|
apply plugin: "kotlin"
|
||||||
|
apply plugin: "net.minecraftforge.gradle.forge"
|
||||||
|
apply from: "https://github.com/shadowfacts/maven/raw/master/maven.gradle"
|
||||||
|
|
||||||
version = mod_version
|
version = mod_version
|
||||||
|
|
||||||
|
@ -31,8 +32,7 @@ minecraft {
|
||||||
|
|
||||||
mappings = mcp_mappings
|
mappings = mcp_mappings
|
||||||
|
|
||||||
replaceIn "Reference.kt"
|
replaceIn "Forgelin.kt"
|
||||||
replaceIn "Reference.kt"
|
|
||||||
replace "@VERSION@", mod_version
|
replace "@VERSION@", mod_version
|
||||||
|
|
||||||
useDepAts = true
|
useDepAts = true
|
||||||
|
@ -52,30 +52,40 @@ processResources {
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
jcenter()
|
||||||
name "shadowfacts"
|
|
||||||
url "http://mvn.rx14.co.uk/shadowfacts/"
|
|
||||||
}
|
|
||||||
maven {
|
|
||||||
url "http://dvs1.progwml6.com/files/maven"
|
|
||||||
}
|
|
||||||
maven {
|
|
||||||
url "http://maven.epoxide.xyz"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile group: "org.jetbrains.kotlin", name: "kotlin-stdlib", version: kotlin_version
|
compile group: "org.jetbrains.kotlin", name: "kotlin-stdlib", version: kotlin_version
|
||||||
|
compile group: "org.jetbrains.kotlin", name: "kotlin-stdlib-jdk7", version: kotlin_version
|
||||||
|
compile group: "org.jetbrains.kotlin", name: "kotlin-stdlib-jdk8", version: kotlin_version
|
||||||
compile group: "org.jetbrains.kotlin", name: "kotlin-reflect", version: kotlin_version
|
compile group: "org.jetbrains.kotlin", name: "kotlin-reflect", version: kotlin_version
|
||||||
compile group: "org.jetbrains.kotlin", name: "kotlin-runtime", version: kotlin_version
|
compile group: "org.jetbrains", name: "annotations", version: annotations_version
|
||||||
|
compile group: "org.jetbrains.kotlinx", name: "kotlinx-coroutines-core", version: coroutines_version
|
||||||
|
compile group: "org.jetbrains.kotlinx", name: "kotlinx-coroutines-jdk8", version: coroutines_version
|
||||||
|
}
|
||||||
|
|
||||||
|
jar {
|
||||||
|
manifest {
|
||||||
|
attributes "FMLCorePlugin": "net.shadowfacts.forgelin.preloader.ForgelinPlugin",
|
||||||
|
"FMLCorePluginContainsFMLMod": "true"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
classifier = ""
|
classifier = ""
|
||||||
dependencies {
|
dependencies {
|
||||||
include(dependency("org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}"))
|
include(dependency("org.jetbrains.kotlin:kotlin-stdlib:${kotlin_version}"))
|
||||||
|
include(dependency("org.jetbrains.kotlin:kotlin-stdlib-jdk7:${kotlin_version}"))
|
||||||
|
include(dependency("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlin_version}"))
|
||||||
include(dependency("org.jetbrains.kotlin:kotlin-reflect:${kotlin_version}"))
|
include(dependency("org.jetbrains.kotlin:kotlin-reflect:${kotlin_version}"))
|
||||||
include(dependency("org.jetbrains.kotlin:kotlin-runtime:${kotlin_version}"))
|
include(dependency("org.jetbrains:annotations:${annotations_version}"))
|
||||||
|
include(dependency("org.jetbrains.kotlinx:kotlinx-coroutines-core:${coroutines_version}"))
|
||||||
|
include(dependency("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:${coroutines_version}"))
|
||||||
|
}
|
||||||
|
manifest {
|
||||||
|
attributes "FMLCorePlugin": "net.shadowfacts.forgelin.preloader.ForgelinPlugin",
|
||||||
|
"FMLCorePluginContainsFMLMod": "true"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,3 +102,5 @@ reobf {
|
||||||
}
|
}
|
||||||
tasks.reobfShadowJar.mustRunAfter shadowJar
|
tasks.reobfShadowJar.mustRunAfter shadowJar
|
||||||
tasks.build.dependsOn reobfShadowJar
|
tasks.build.dependsOn reobfShadowJar
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
mod_version = 1.3.0
|
mod_version = 1.8.4
|
||||||
group = net.shadowfacts
|
group = net.shadowfacts
|
||||||
archivesBaseName = Forgelin
|
archivesBaseName = Forgelin
|
||||||
|
|
||||||
mc_version = 1.10.2
|
mc_version = 1.12.2
|
||||||
mcp_mappings = snapshot_20160802
|
mcp_mappings = snapshot_20180609
|
||||||
forge_version = 12.18.1.2045
|
forge_version = 14.23.4.2705
|
||||||
|
|
||||||
kotlin_version = 1.0.6
|
kotlin_version = 1.3.50
|
||||||
|
annotations_version = 16.0.3
|
||||||
|
coroutines_version = 1.3.1
|
||||||
|
|
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package net.shadowfacts.forgelin.preloader;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
public class ForgelinPlugin implements IFMLLoadingPlugin {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getASMTransformerClass() {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getModContainerClass() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSetupClass() {
|
||||||
|
return "net.shadowfacts.forgelin.preloader.ForgelinSetup";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void injectData(Map<String, Object> data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAccessTransformerClass() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package net.shadowfacts.forgelin.preloader;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.relauncher.IFMLCallHook;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
public class ForgelinSetup implements IFMLCallHook {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void injectData(Map<String, Object> data) {
|
||||||
|
ClassLoader loader = (ClassLoader)data.get("classLoader");
|
||||||
|
try {
|
||||||
|
loader.loadClass("net.shadowfacts.forgelin.KotlinAdapter");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
// this should never happen
|
||||||
|
throw new RuntimeException("Couldn't find Forgelin langague adapter, this shouldn't be happening", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void call() throws Exception {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,10 @@
|
||||||
package net.shadowfacts.forgelin
|
package net.shadowfacts.forgelin
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.common.FMLCommonHandler
|
||||||
|
import net.minecraftforge.fml.common.Loader
|
||||||
import net.minecraftforge.fml.common.Mod
|
import net.minecraftforge.fml.common.Mod
|
||||||
|
import net.minecraftforge.fml.common.Mod.EventHandler
|
||||||
|
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
|
@ -10,6 +14,12 @@ object Forgelin {
|
||||||
|
|
||||||
const val MOD_ID = "forgelin"
|
const val MOD_ID = "forgelin"
|
||||||
const val NAME = "Forgelin"
|
const val NAME = "Forgelin"
|
||||||
const val VERSION = "1.3.0"
|
const val VERSION = "@VERSION@"
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun onPreInit(event: FMLPreInitializationEvent) {
|
||||||
|
Loader.instance().modList.forEach {
|
||||||
|
ForgelinAutomaticEventSubscriber.subscribeAutomatic(it, event.asmData, FMLCommonHandler.instance().side)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
package net.shadowfacts.forgelin
|
||||||
|
|
||||||
|
import net.minecraftforge.common.MinecraftForge
|
||||||
|
import net.minecraftforge.fml.common.Loader
|
||||||
|
import net.minecraftforge.fml.common.LoaderException
|
||||||
|
import net.minecraftforge.fml.common.Mod
|
||||||
|
import net.minecraftforge.fml.common.ModContainer
|
||||||
|
import net.minecraftforge.fml.common.discovery.ASMDataTable
|
||||||
|
import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData
|
||||||
|
import net.minecraftforge.fml.common.discovery.asm.ModAnnotation.EnumHolder
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
||||||
|
import net.minecraftforge.fml.relauncher.Side
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
|
import java.lang.reflect.Modifier
|
||||||
|
import java.util.EnumSet
|
||||||
|
import kotlin.reflect.full.companionObjectInstance
|
||||||
|
|
||||||
|
object ForgelinAutomaticEventSubscriber {
|
||||||
|
private val DEFAULT_SUBSCRIPTION_SIDES = EnumSet.allOf(Side::class.java)
|
||||||
|
private val LOGGER = LogManager.getLogger(ForgelinAutomaticEventSubscriber::class.java)
|
||||||
|
|
||||||
|
private val unregistered = mutableSetOf<Class<*>>()
|
||||||
|
private val registered = mutableSetOf<Any>()
|
||||||
|
|
||||||
|
fun subscribeAutomatic(mod: ModContainer, asm: ASMDataTable, currentSide: Side) {
|
||||||
|
val modAnnotations = asm.getAnnotationsFor(mod) ?: return
|
||||||
|
|
||||||
|
val containedMods = modAnnotations.get(Mod::class.java.name)
|
||||||
|
val subscribers = modAnnotations.get(Mod.EventBusSubscriber::class.java.name)
|
||||||
|
.filter { parseTargetSides(it).contains(currentSide) }
|
||||||
|
|
||||||
|
val loader = Loader.instance().modClassLoader
|
||||||
|
|
||||||
|
|
||||||
|
for (containedMod in containedMods) {
|
||||||
|
val containedModId = containedMod.annotationInfo["modid"] as String
|
||||||
|
if (containedMod.annotationInfo["modLanguageAdapter"] != KotlinAdapter::class.qualifiedName) {
|
||||||
|
LOGGER.debug("Skipping @EventBusSubscriber injection for {} since it does not use KotlinAdapter", containedModId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.debug("Attempting to register Kotlin @EventBusSubscriber objects for {}", containedModId)
|
||||||
|
|
||||||
|
for (subscriber in subscribers) {
|
||||||
|
try {
|
||||||
|
val ownerModId = parseModId(containedMods, subscriber)
|
||||||
|
if (ownerModId.isNullOrEmpty()) {
|
||||||
|
LOGGER.debug("Could not determine owning mod for @EventBusSubscriber on {} for mod {}", subscriber.className, mod.modId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containedModId != ownerModId) {
|
||||||
|
LOGGER.debug("Skipping @EventBusSubscriber injection for {} since it is not for mod {}", subscriber.className, containedModId)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val subscriberClass = Class.forName(subscriber.className, false, loader) ?: continue
|
||||||
|
val kotlinClass = subscriberClass.kotlin
|
||||||
|
val objectInstance = kotlinClass.objectInstance ?: kotlinClass.companionObjectInstance ?: continue
|
||||||
|
|
||||||
|
if (!hasStaticEventHandlers(subscriberClass) && subscriberClass !in unregistered) {
|
||||||
|
MinecraftForge.EVENT_BUS.unregister(subscriberClass)
|
||||||
|
unregistered += subscriberClass
|
||||||
|
LOGGER.debug("Unregistered static @EventBusSubscriber class {}", subscriber.className)
|
||||||
|
}
|
||||||
|
if (hasObjectEventHandlers(objectInstance) && objectInstance !in registered) {
|
||||||
|
MinecraftForge.EVENT_BUS.register(objectInstance)
|
||||||
|
registered += objectInstance
|
||||||
|
LOGGER.debug("Registered @EventBusSubscriber object instance {}", subscriber.className)
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
LOGGER.error("An error occurred trying to load an @EventBusSubscriber object {} for modid {}", mod.modId, e)
|
||||||
|
throw LoaderException(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hasObjectEventHandlers(objectInstance: Any): Boolean {
|
||||||
|
return objectInstance.javaClass.methods.any {
|
||||||
|
!Modifier.isStatic(it.modifiers) && it.isAnnotationPresent(SubscribeEvent::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hasStaticEventHandlers(clazz: Class<*>): Boolean {
|
||||||
|
return clazz.methods.any {
|
||||||
|
Modifier.isStatic(it.modifiers) && it.isAnnotationPresent(SubscribeEvent::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun parseModId(containedMods: MutableSet<ASMData>, subscriber: ASMData): String? {
|
||||||
|
val parsedModId: String? = subscriber.annotationInfo["modid"] as? String
|
||||||
|
if (parsedModId.isNullOrEmpty()) {
|
||||||
|
return parsedModId
|
||||||
|
}
|
||||||
|
|
||||||
|
return ASMDataTable.getOwnerModID(containedMods, subscriber)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun parseTargetSides(subscriber: ASMData): EnumSet<Side> {
|
||||||
|
val parsedSides: List<EnumHolder>? = subscriber.annotationInfo["value"] as? List<EnumHolder>
|
||||||
|
if (parsedSides != null) {
|
||||||
|
val targetSides = EnumSet.noneOf(Side::class.java)
|
||||||
|
for (parsed in parsedSides) {
|
||||||
|
targetSides.add(Side.valueOf(parsed.value))
|
||||||
|
}
|
||||||
|
return targetSides
|
||||||
|
}
|
||||||
|
return DEFAULT_SUBSCRIPTION_SIDES
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"modid": "forgelin",
|
||||||
|
"name": "Shadowfacts' Forgelin",
|
||||||
|
"version": "$version",
|
||||||
|
"mcversion": "$mcversion",
|
||||||
|
"description": "Kotlin helper library for Forge.",
|
||||||
|
"credits": "Emberwalker, for the original Forgelin",
|
||||||
|
"url": "https://github.com/shadowfacts/Forgelin",
|
||||||
|
"updateUrl": "",
|
||||||
|
"authorList": [ "shadowfacts" ],
|
||||||
|
"screenshots": []
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,26 @@
|
||||||
|
package net.shadowfacts.forgelin
|
||||||
|
|
||||||
|
import net.minecraftforge.event.entity.player.PlayerInteractEvent
|
||||||
|
import net.minecraftforge.event.entity.player.PlayerInteractEvent.RightClickBlock
|
||||||
|
import net.minecraftforge.fml.common.Mod
|
||||||
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
||||||
|
|
||||||
|
@Mod(modid = AutomaticKtSubscriberTest.MODID, modLanguageAdapter = "net.shadowfacts.forgelin.KotlinAdapter")
|
||||||
|
object AutomaticKtSubscriberTest {
|
||||||
|
const val MODID = "ktsubtest"
|
||||||
|
|
||||||
|
@EventBusSubscriber(modid = AutomaticKtSubscriberTest.MODID)
|
||||||
|
object EventSubscriber {
|
||||||
|
@SubscribeEvent
|
||||||
|
fun onRightClickBlock(event: RightClickBlock) {
|
||||||
|
println("Automatic KT subscriber: Right click ${event.pos}")
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@SubscribeEvent
|
||||||
|
fun onRightClickItem(event: PlayerInteractEvent.RightClickItem) {
|
||||||
|
println("Right click item")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue