Compare commits

..

No commits in common. "master" and "1.3.0" have entirely different histories.

10 changed files with 27 additions and 271 deletions

View File

@ -2,15 +2,14 @@
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, coroutines-core, and reflect libraries so you don't have to. - Shades the Kotlin standard library, runtime, 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://maven.shadowfacts.net/" url "http://mvn.rx14.co.uk/shadowfacts/"
} }
} }
@ -19,6 +18,4 @@ dependencies {
} }
``` ```
All versions can be seen [here](http://maven.shadowfacts.net/net/shadowfacts/Forgelin/). All versions can be seen [here](http://mvn.rx14.co.uk/shadowfacts/net/shadowfacts/Forgelin/).
**Note:** You must have the `jcenter()` call in your `repositories` block. JCenter is used to host the Kotlin coroutines libraries.

View File

@ -7,7 +7,7 @@ buildscript {
} }
} }
dependencies { dependencies {
classpath "net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT" classpath "net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlin_version}"
} }
} }
@ -17,9 +17,8 @@ plugins {
id "com.github.johnrengelman.shadow" version "1.2.3" id "com.github.johnrengelman.shadow" version "1.2.3"
} }
apply plugin: "kotlin"
apply plugin: "net.minecraftforge.gradle.forge" apply plugin: "net.minecraftforge.gradle.forge"
apply from: "https://github.com/shadowfacts/maven/raw/master/maven.gradle" apply plugin: "kotlin"
version = mod_version version = mod_version
@ -32,7 +31,8 @@ minecraft {
mappings = mcp_mappings mappings = mcp_mappings
replaceIn "Forgelin.kt" replaceIn "Reference.kt"
replaceIn "Reference.kt"
replace "@VERSION@", mod_version replace "@VERSION@", mod_version
useDepAts = true useDepAts = true
@ -52,40 +52,30 @@ processResources {
} }
repositories { repositories {
jcenter() maven {
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", name: "annotations", version: annotations_version compile group: "org.jetbrains.kotlin", name: "kotlin-runtime", version: kotlin_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:annotations:${annotations_version}")) include(dependency("org.jetbrains.kotlin:kotlin-runtime:${kotlin_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"
} }
} }
@ -102,5 +92,3 @@ reobf {
} }
tasks.reobfShadowJar.mustRunAfter shadowJar tasks.reobfShadowJar.mustRunAfter shadowJar
tasks.build.dependsOn reobfShadowJar tasks.build.dependsOn reobfShadowJar

View File

@ -1,11 +1,9 @@
mod_version = 1.8.4 mod_version = 1.3.0
group = net.shadowfacts group = net.shadowfacts
archivesBaseName = Forgelin archivesBaseName = Forgelin
mc_version = 1.12.2 mc_version = 1.10.2
mcp_mappings = snapshot_20180609 mcp_mappings = snapshot_20160802
forge_version = 14.23.4.2705 forge_version = 12.18.1.2045
kotlin_version = 1.3.50 kotlin_version = 1.0.6
annotations_version = 16.0.3
coroutines_version = 1.3.1

View File

@ -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-4.10.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip

View File

@ -1,37 +0,0 @@
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;
}
}

View File

@ -1,28 +0,0 @@
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;
}
}

View File

@ -1,10 +1,6 @@
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
@ -14,12 +10,6 @@ object Forgelin {
const val MOD_ID = "forgelin" const val MOD_ID = "forgelin"
const val NAME = "Forgelin" const val NAME = "Forgelin"
const val VERSION = "@VERSION@" const val VERSION = "1.3.0"
@EventHandler }
fun onPreInit(event: FMLPreInitializationEvent) {
Loader.instance().modList.forEach {
ForgelinAutomaticEventSubscriber.subscribeAutomatic(it, event.asmData, FMLCommonHandler.instance().side)
}
}
}

View File

@ -1,112 +0,0 @@
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
}
}

View File

@ -1,14 +0,0 @@
[
{
"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": []
}
]

View File

@ -1,26 +0,0 @@
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")
}
}
}