aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md17
-rw-r--r--build.gradle18
-rw-r--r--changelog.md (renamed from changelog.txt)15
-rw-r--r--gradle.properties4
-rw-r--r--src/example/kotlin/thedarkcolour/kotlinforforge/ExampleMod.kt80
-rw-r--r--src/example/kotlin/thedarkcolour/kotlinforforge/package.md7
-rw-r--r--src/example/kotlin/thedarkcolour/kotlinforforge/proxy/Proxies.kt20
-rw-r--r--src/example/kotlin/thedarkcolour/kotlinforforge/proxy/package.md12
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/AutoKotlinEventBusSubscriber.kt18
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt11
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt7
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModContainer.kt50
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModLoadingContext.kt10
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/eventbus/KotlinEventBus.kt41
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/eventbus/KotlinEventBusWrapper.kt18
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt83
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/kotlin/Kotlin.kt20
-rw-r--r--src/main/kotlin/thedarkcolour/kotlinforforge/kotlin/package.md2
-rw-r--r--src/main/resources/META-INF/mods.toml4
-rw-r--r--thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0-sources.jarbin0 -> 31884 bytes
-rw-r--r--thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0-sources.jar.md51
-rw-r--r--thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0-sources.jar.sha11
-rw-r--r--thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.jarbin0 -> 89549 bytes
-rw-r--r--thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.jar.md51
-rw-r--r--thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.jar.sha11
-rw-r--r--thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.pom60
-rw-r--r--thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.pom.md51
-rw-r--r--thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.pom.sha11
-rw-r--r--thedarkcolour/kotlinforforge/1.3.0/web.html20
-rw-r--r--thedarkcolour/kotlinforforge/maven-metadata.xml4
-rw-r--r--thedarkcolour/kotlinforforge/web.html1
31 files changed, 313 insertions, 215 deletions
diff --git a/README.md b/README.md
index ef3807f..8a00d7d 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,14 @@ Makes Kotlin forge-friendly by doing the following:
- Provides `KotlinLanguageProvider` to allow usage of object declarations as @Mod targets.
- Provides `AutoKotlinEventBusSubscriber` to allow usage of object declarations as @Mod.EventBusSubscriber targets.
- Provides useful utility functions and constants
+- Provides its own implementation of the Forge eventbus to work with KCallables and reified type parameters
+- Provides sided property delegates and object holder property delegates
+
+An example mod is provided at the [KotlinModdingSkeleton repository](https://github.com/thedarkcolour/KotlinModdingSkeleton).
+If you aren't sure where to start, make a fork of the KotlinModdingSkeleton repository.
+```git
+git clone https://github.com/thedarkcolour/KotlinModdingSkeleton.git
+```
To implement in your project, paste the following into your build.gradle:
```groovy
@@ -14,7 +22,7 @@ buildscript {
}
dependencies {
// Make sure to use the correct version
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4-M1"
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4-M2"
}
}
@@ -33,7 +41,7 @@ repositories {
dependencies {
// Use the latest version of KotlinForForge
- implementation 'thedarkcolour:kotlinforforge:1.2.2'
+ implementation 'thedarkcolour:kotlinforforge:1.2.3'
}
compileKotlin {
@@ -44,11 +52,6 @@ compileKotlin {
languageVersion = '1.4'
apiVersion = '1.4'
}
-
- // Required to run in dev environment
- copy {
- from "$buildDir/classes/kotlin/main" into "$buildDir/classes/java/main"
- }
}
```
Then, change the following to your mods.toml file:
diff --git a/build.gradle b/build.gradle
index d9b563e..0722f28 100644
--- a/build.gradle
+++ b/build.gradle
@@ -20,7 +20,7 @@ apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'kotlin'
apply plugin: 'org.jetbrains.dokka'
-version = "1.2.2"
+version = "1.3.0"
group = 'thedarkcolour.kotlinforforge'
archivesBaseName = 'kotlinforforge'
@@ -120,15 +120,19 @@ jar {
compileKotlin {
kotlinOptions {
jvmTarget = '1.8'
+ freeCompilerArgs = ["-Xexplicit-api=warning"]
}
- // Required to run in dev environment
- copy {
- from "$buildDir/classes/kotlin/main" into "$buildDir/classes/java/main"
- }
+}
+
+sourceSets.test {
+ kotlin.srcDirs 'src/example/kotlin'
+ resources.srcDirs 'src/example/resources'
}
kotlinSourcesJar {
- from(sourceSets.main.kotlin.srcDirs)
+ from(sourceSets.main.kotlin.srcDirs).eachFile { file ->
+ println(file.name)
+ }
}
dokka {
@@ -138,6 +142,6 @@ dokka {
configuration {
reportUndocumented = true
- samples = ["$rootDir/src/test/kotlin/thedarkcolour/kotlinforforge/ExampleMod.kt".toString()]
+ samples = ["$rootDir/src/test/kotlin/thedarkcolour/example/ExampleMod.kt".toString()]
}
} \ No newline at end of file
diff --git a/changelog.txt b/changelog.md
index 3f38229..d4fdf03 100644
--- a/changelog.txt
+++ b/changelog.md
@@ -1,8 +1,15 @@
+Kotlin for Forge 1.3.0
+- Added a modding skeleton repository as an alternative to editing the build.gradle the Forge MDK ships with.
+- Added two more reified generic functions to the KotlinEventBus for `priority` and `receivedCancelled` parameters.
+- Fixed the ObjectHolderDelegate not allowing subtypes of classes that implement IForgeRegistryEntry
+- Updated to Kotlin 1.4-M2, Updated to coroutines 1.3.7
+- **KFF 1.3.x is not compatible with versions earlier than 1.2.3 due to Kotlin Reflection changes in 1.4-M2**
+
Kotlin for Forge 1.2.2
-- Added a sided delegate class that returns a "client value" on the client side and a "server value" on the server side.
+- Added a sided delegate class which returns a "client value" on the client side and a "server value" on the server side.
- Added a new utility file called "Kotlin.kt" that provides a few utility functions not related to Minecraft Forge.
- Added an example mod. I will make a template GitHub repository for Kotlin for Forge soon.
-- Adjusted mod construction to accurately report exceptions in @Mod object initializers
+- Adjusted mod construction to accurately report exceptions in @Mod object constructors
- Restructured Kotlin for Forge code to use Kotlin APIs whenever possible
- Added styling to the maven repo
@@ -12,11 +19,11 @@ Kotlin for Forge 1.2.1
Kotlin for Forge 1.2.0
- Added a Kotlin implementation of the Forge EventBus that has working addListener and addGenericListener functions
- Added an overload of addGenericListener that uses a reified type parameter instead of a class parameter.
-- Updated to Kotlin 1.4M1
+- Updated to Kotlin 1.4-M1
Kotlin for Forge 1.1.0
- Events now properly fire through KotlinModContainer
-- Updated to Kotlin 1.3.70 Updated to coroutines 1.3.4 Updated to Jetbrains annotation 19.0.0
+- Updated to Kotlin 1.3.70, Updated to coroutines 1.3.4, Updated to JetBrains annotations 19.0.0
Kotlin for Forge 1.0.1
- Fixed an issue with language extensions
diff --git a/gradle.properties b/gradle.properties
index c4f4ba4..8ee44fd 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -2,6 +2,6 @@
# This is required to provide enough memory for the Minecraft decompilation process.
org.gradle.jvmargs=-Xmx3G
org.gradle.daemon=false
-kotlin_version=1.4-M1
-coroutines_version = 1.3.4
+kotlin_version=1.4-M2
+coroutines_version = 1.3.7
annotations_version = 19.0.0 \ No newline at end of file
diff --git a/src/example/kotlin/thedarkcolour/kotlinforforge/ExampleMod.kt b/src/example/kotlin/thedarkcolour/kotlinforforge/ExampleMod.kt
deleted file mode 100644
index af01493..0000000
--- a/src/example/kotlin/thedarkcolour/kotlinforforge/ExampleMod.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-package thedarkcolour.kotlinforforge
-
-import net.minecraft.block.Block
-import net.minecraftforge.event.RegistryEvent
-import net.minecraftforge.eventbus.api.SubscribeEvent
-import net.minecraftforge.fml.common.Mod
-import net.minecraftforge.fml.event.server.FMLServerStartingEvent
-import thedarkcolour.kotlinforforge.forge.MOD_BUS
-import thedarkcolour.kotlinforforge.forge.lazySidedDelegate
-import thedarkcolour.kotlinforforge.proxy.ClientProxy
-import thedarkcolour.kotlinforforge.proxy.IProxy
-import thedarkcolour.kotlinforforge.proxy.ServerProxy
-
-/**
- * Example mod for anyone who'd like to see
- * how a mod would be made with Kotlin for Forge.
- *
- * This mod has a modid of "examplemod", listens
- * for the ``RegistryEvent.Register<Block>`` and
- * for the ``FMLServerStartingEvent``.
- *
- * It registers event listeners by adding event listeners
- * directly to the event buses KFF provides and
- * by using the ``@EventBusSubscriber`` annotation.
- */
-@Mod(ExampleMod.ID)
-object ExampleMod {
- /**
- * Your mod's ID
- */
- const val ID = "examplemod"
-
- /**
- * The sided proxy. Since we use a lazy sided delegate,
- * the supplier parameters are invoked only once.
- */
- private val proxy by lazySidedDelegate(::ClientProxy, ::ServerProxy)
-
- /**
- * Example of using the KotlinEventBus
- * to register a function reference.
- *
- * Event classes with a generic type
- * should be registered using ``addGenericListener``
- * instead of ``addListener``.
- */
- init {
- MOD_BUS.addGenericListener(::registerBlocks)
-
- proxy.modConstruction()
- }
-
- /**
- * Handle block registry here.
- */
- private fun registerBlocks(event: RegistryEvent.Register<Block>) {
- // ...
- }
-
- /**
- * Example of an object class using the
- * ``@Mod.EventBusSubscriber`` annotation
- * to automatically subscribe functions
- * to the forge event bus.
- *
- * Even though the ``Bus.FORGE`` event bus
- * is default, I think that it's still
- * a good practice to specify the bus explicitly.
- */
- @Mod.EventBusSubscriber(modid = ExampleMod.ID, bus = Mod.EventBusSubscriber.Bus.FORGE)
- object EventHandler {
- /**
- * Handles things like registering commands.
- */
- @SubscribeEvent
- fun onServerStarting(event: FMLServerStartingEvent) {
- // ...
- }
- }
-} \ No newline at end of file
diff --git a/src/example/kotlin/thedarkcolour/kotlinforforge/package.md b/src/example/kotlin/thedarkcolour/kotlinforforge/package.md
deleted file mode 100644
index c9c1caa..0000000
--- a/src/example/kotlin/thedarkcolour/kotlinforforge/package.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# thedarkcolour.kotlinforforge
-This package contains an example main mod class
-for a mod using Kotlin for Forge.
-
-## ExampleMod
-Your main mod class should be an object declaration.
-It must be annotated with the @Mod annotation. \ No newline at end of file
diff --git a/src/example/kotlin/thedarkcolour/kotlinforforge/proxy/Proxies.kt b/src/example/kotlin/thedarkcolour/kotlinforforge/proxy/Proxies.kt
deleted file mode 100644
index 24c51b7..0000000
--- a/src/example/kotlin/thedarkcolour/kotlinforforge/proxy/Proxies.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package thedarkcolour.kotlinforforge.proxy
-
-/**
- * Common inheritor of both proxies.
- */
-interface IProxy {
- fun modConstruction()
-}
-
-class ClientProxy : IProxy {
- override fun modConstruction() {
- // run client code
- }
-}
-
-class ServerProxy : IProxy {
- override fun modConstruction() {
- // run server code
- }
-} \ No newline at end of file
diff --git a/src/example/kotlin/thedarkcolour/kotlinforforge/proxy/package.md b/src/example/kotlin/thedarkcolour/kotlinforforge/proxy/package.md
deleted file mode 100644
index bb57203..0000000
--- a/src/example/kotlin/thedarkcolour/kotlinforforge/proxy/package.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# thedarkcolour.kotlinforforge.proxy
-This package has example proxy classes.
-Proxies are used to provide common declarations with sided implementations.
-
-Forge no longer supports the proxy pattern.
-The ``@SidedProxy`` annotation was removed in 1.13+.
-This example shows a use case for the ``lazySidedDelegate``.
-It is recommended to use the ``runWhenOn`` and ``callWhenOn`` functions
-instead of proxies whenever possible.
-
-In this example, a proxy is instantiated lazily in the ``ExampleMod`` class.
-Proxies are not the only use for sided delegates. \ No newline at end of file
diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/AutoKotlinEventBusSubscriber.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/AutoKotlinEventBusSubscriber.kt
index 01a10c0..78325ee 100644
--- a/src/main/kotlin/thedarkcolour/kotlinforforge/AutoKotlinEventBusSubscriber.kt
+++ b/src/main/kotlin/thedarkcolour/kotlinforforge/AutoKotlinEventBusSubscriber.kt
@@ -19,26 +19,28 @@ import thedarkcolour.kotlinforforge.kotlin.enumSet
* @see MOD_BUS
* @see FORGE_BUS
*/
-object AutoKotlinEventBusSubscriber {
+public object AutoKotlinEventBusSubscriber {
+ /** The [Mod.EventBusSubscriber] java type. */
private val EVENT_BUS_SUBSCRIBER: Type = Type.getType(Mod.EventBusSubscriber::class.java)
+ /** The default (client & server) list of [Dist] enum holders. */
private val DIST_ENUM_HOLDERS = listOf(
ModAnnotation.EnumHolder(null, "CLIENT"),
ModAnnotation.EnumHolder(null, "DEDICATED_SERVER")
)
/**
- * Allows the Mod.EventBusSubscriber annotation
+ * Allows the [Mod.EventBusSubscriber] annotation
* to target member functions of an `object` class.
*
* You **must** be using an `object` class, or the
- * EventBusSubscriber annotation will ignore it.
+ * `Mod.EventBusSubscriber` annotation will ignore it.
*
- * Personally, I am against using [Mod.EventBusSubscriber]
- * because it makes
- *
- * @sample thedarkcolour.kotlinforforge.ExampleMod
+ * I am against using `Mod.EventBusSubscriber`
+ * because it makes it difficult to follow where event
+ * listeners are registered. Instead, prefer to directly
+ * register event listeners to the [FORGE_BUS] or [MOD_BUS].
*/
- fun inject(mod: ModContainer, scanData: ModFileScanData, classLoader: ClassLoader) {
+ public fun inject(mod: ModContainer, scanData: ModFileScanData, classLoader: ClassLoader) {
LOGGER.debug(Logging.LOADING, "Attempting to inject @EventBusSubscriber kotlin objects in to the event bus for ${mod.modId}")
val data = scanData.annotations.filter { annotationData ->
diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt
index 6a60e4b..eeaaef4 100644
--- a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt
+++ b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinForForge.kt
@@ -4,9 +4,14 @@ import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext
/**
- * Set 'modLoader' in mods.toml to "kotlinforforge" and loaderVersion to "[1,)".
+ * Set `modLoader` in mods.toml to
+ * `"kotlinforforge"` and loaderVersion to `"[1.3,1.4)"`.
*
- * Make sure to use [KotlinModLoadingContext] instead of [FMLJavaModLoadingContext].
+ * Make sure to use [KotlinModLoadingContext]
+ * instead of [FMLJavaModLoadingContext].
+ *
+ * For a more thorough example mod,
+ * check out the [KotlinModdingSkeleton repository](https://github.com/thedarkcolour/KotlinModdingSkeleton).
*/
@Mod("kotlinforforge")
-object KotlinForForge \ No newline at end of file
+public object KotlinForForge \ No newline at end of file
diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt
index a06c9a3..e2ee9ff 100644
--- a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt
+++ b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinLanguageProvider.kt
@@ -10,8 +10,8 @@ import java.util.function.Consumer
/**
* Reuse a bit of code from FMLJavaModLanguageProvider
*/
-class KotlinLanguageProvider : FMLJavaModLanguageProvider() {
- override fun name() = "kotlinforforge"
+public class KotlinLanguageProvider : FMLJavaModLanguageProvider() {
+ override fun name(): String = "kotlinforforge"
override fun getFileVisitor(): Consumer<ModFileScanData> {
return Consumer { scanData ->
@@ -20,6 +20,7 @@ class KotlinLanguageProvider : FMLJavaModLanguageProvider() {
}.map { data ->
val modid = data.annotationData["value"] as String
val modClass = data.classType.className
+
LOGGER.debug(Logging.SCAN, "Found @Mod class $modClass with mod id $modid")
modid to KotlinModTarget(modClass)
}.toMap()
@@ -28,7 +29,7 @@ class KotlinLanguageProvider : FMLJavaModLanguageProvider() {
}
}
- class KotlinModTarget constructor(private val className: String) : IModLanguageProvider.IModLanguageLoader {
+ public class KotlinModTarget constructor(private val className: String) : IModLanguageProvider.IModLanguageLoader {
override fun <T> loadMod(info: IModInfo, modClassLoader: ClassLoader, modFileScanResults: ModFileScanData): T {
val ktContainer = Class.forName("thedarkcolour.kotlinforforge.KotlinModContainer", true, Thread.currentThread().contextClassLoader)
val constructor = ktContainer.declaredConstructors[0]
diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModContainer.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModContainer.kt
index e86f66a..9a7c308 100644
--- a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModContainer.kt
+++ b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModContainer.kt
@@ -17,14 +17,28 @@ import thedarkcolour.kotlinforforge.eventbus.KotlinEventBus
import thedarkcolour.kotlinforforge.kotlin.supply
import java.util.function.Consumer
-typealias LifeCycleEventListener = (LifecycleEvent) -> Unit
+public typealias LifecycleEventListener = (LifecycleEvent) -> Unit
/**
- * Functions as [net.minecraftforge.fml.javafmlmod.FMLModContainer] for Kotlin
+ * The Kotlin for Forge `ModContainer`.
*/
-class KotlinModContainer(private val info: IModInfo, private val className: String, private val classLoader: ClassLoader, private val scanData: ModFileScanData) : ModContainer(info) {
+public class KotlinModContainer(
+ private val info: IModInfo,
+ private val className: String,
+ private val classLoader: ClassLoader,
+ private val scanData: ModFileScanData,
+) : ModContainer(info) {
+
+ /**
+ * The `@Mod` object or instance of the `@Mod` class.
+ */
private lateinit var modInstance: Any
- val eventBus: KotlinEventBus
+
+ /**
+ * The `IEventBus` for Kotlin for Forge mods
+ * that supports `KCallable` event listeners.
+ */
+ public val eventBus: KotlinEventBus
init {
LOGGER.debug(Logging.LOADING, "Creating KotlinModContainer instance for {} with classLoader {} & {}", className, classLoader, javaClass.classLoader)
@@ -41,9 +55,13 @@ class KotlinModContainer(private val info: IModInfo, private val className: Stri
contextExtension = supply(KotlinModLoadingContext(this))
}
- private inline fun createTrigger(
- crossinline consumerA: LifeCycleEventListener,
- crossinline consumerB: LifeCycleEventListener,
+ /**
+ * Creates a single `Consumer` that calls
+ * both [consumerA] and [consumerB].
+ */
+ private fun createTrigger(
+ consumerA: LifecycleEventListener,
+ consumerB: LifecycleEventListener,
): Consumer<LifecycleEvent> {
return Consumer { event ->
consumerA(event)
@@ -51,12 +69,20 @@ class KotlinModContainer(private val info: IModInfo, private val className: Stri
}
}
+ /**
+ * The `IEventExceptionHandler` that logs
+ * errors in events as errors.
+ */
private fun onEventFailed(iEventBus: IEventBus, event: Event, iEventListeners: Array<IEventListener>, i: Int, throwable: Throwable) {
LOGGER.error(EventBusErrorMessage(event, i, iEventListeners, throwable))
}
+ /**
+ * Fires a `LifecycleEvent` on the mod [eventBus].
+ */
private fun fireEvent(lifecycleEvent: LifecycleEvent) {
val event = lifecycleEvent.getOrBuildEvent(this)
+
LOGGER.debug(Logging.LOADING, "Firing event for modid $modId : $event")
try {
@@ -68,14 +94,22 @@ class KotlinModContainer(private val info: IModInfo, private val className: Stri
}
}
+ /**
+ * If an error was thrown during the event,
+ * log it to the console as an error.
+ */
private fun afterEvent(lifecycleEvent: LifecycleEvent) {
if (currentState == ModLoadingStage.ERROR) {
LOGGER.error(Logging.LOADING, "An error occurred while dispatching event ${lifecycleEvent.fromStage()} to $modId")
}
}
+ /**
+ * Initializes [modInstance] and calls the mod constructor
+ */
private fun constructMod(lifecycleEvent: LifecycleEvent) {
val modClass: Class<*>
+
try {
modClass = Class.forName(className, false, classLoader)
LOGGER.debug(Logging.LOADING, "Loaded kotlin modclass ${modClass.name} with ${modClass.classLoader}")
@@ -112,7 +146,7 @@ class KotlinModContainer(private val info: IModInfo, private val className: Stri
return mod == modInstance
}
- override fun getMod() = modInstance
+ override fun getMod(): Any = modInstance
override fun acceptEvent(e: Event) {
eventBus.post(e)
diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModLoadingContext.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModLoadingContext.kt
index 8d0029f..128b399 100644
--- a/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModLoadingContext.kt
+++ b/src/main/kotlin/thedarkcolour/kotlinforforge/KotlinModLoadingContext.kt
@@ -7,11 +7,11 @@ import thedarkcolour.kotlinforforge.forge.LOADING_CONTEXT
/**
* Mod loading context for mods made with Kotlin for Forge.
*/
-class KotlinModLoadingContext constructor(private val container: KotlinModContainer) {
+public class KotlinModLoadingContext constructor(private val container: KotlinModContainer) {
/** @since 1.2.1
* @see thedarkcolour.kotlinforforge.forge.MOD_BUS
*/
- fun getKEventBus(): KotlinEventBus {
+ public fun getKEventBus(): KotlinEventBus {
return container.eventBus
}
@@ -25,15 +25,15 @@ class KotlinModLoadingContext constructor(private val container: KotlinModContai
replaceWith = ReplaceWith("getKEventBus()"),
level = DeprecationLevel.WARNING,
)
- fun getEventBus(): IEventBus {
+ public fun getEventBus(): IEventBus {
return container.eventBus
}
- companion object {
+ public companion object {
/**
* Returns the [KotlinModLoadingContext] for the current mod
*/
- fun get(): KotlinModLoadingContext {
+ public fun get(): KotlinModLoadingContext {
return LOADING_CONTEXT.extension()
}
}
diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/eventbus/KotlinEventBus.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/eventbus/KotlinEventBus.kt
index 7bf575e..c35c4e9 100644
--- a/src/main/kotlin/thedarkcolour/kotlinforforge/eventbus/KotlinEventBus.kt
+++ b/src/main/kotlin/thedarkcolour/kotlinforforge/eventbus/KotlinEventBus.kt
@@ -19,14 +19,14 @@ import java.util.function.Consumer
/** @since 1.2.0
* Fixes [addListener] and [addGenericListener] for Kotlin KCallable.
*/
-open class KotlinEventBus(builder: BusBuilder, synthetic: Boolean = false) : IEventBus, IEventExceptionHandler {
+public open class KotlinEventBus(builder: BusBuilder, synthetic: Boolean = false) : IEventBus, IEventExceptionHandler {
@Suppress("LeakingThis")
private val exceptionHandler = builder.exceptionHandler ?: this
private val trackPhases = builder.trackPhases
@Volatile
private var shutdown = builder.isStartingShutdown
- protected open val busID = MAX_ID.getAndIncrement()
- protected open val listeners = ConcurrentHashMap<Any, MutableList<IEventListener>>()
+ protected open val busID: Int = MAX_ID.getAndIncrement()
+ protected open val listeners: ConcurrentHashMap<Any, MutableList<IEventListener>> = ConcurrentHashMap()
init {
// see companion object
@@ -201,11 +201,42 @@ open class KotlinEventBus(builder: BusBuilder, synthetic: Boolean = false) : IEv
* @param T The [GenericEvent] subclass to listen for
* @param F The [Class] to filter the [GenericEvent] for
*/
- inline fun <T : GenericEvent<out F>, reified F> addGenericListener(consumer: Consumer<T>) {
+ public inline fun <T : GenericEvent<out F>, reified F> addGenericListener(consumer: Consumer<T>) {
addGenericListener(F::class.java, consumer)
}
/**
+ * Add a consumer listener with the specified [EventPriority] and not receiving cancelled events,
+ * for a [GenericEvent] subclass, filtered to only be called for the specified
+ * filter [Class].
+ *
+ * @param genericClassFilter A [Class] which the [GenericEvent] should be filtered for
+ * @param priority [EventPriority] for this listener
+ * @param consumer Callback to invoke when a matching event is received
+ * @param T The [GenericEvent] subclass to listen for
+ * @param F The [Class] to filter the [GenericEvent] for
+ */
+ public inline fun <T : GenericEvent<out F>, reified F> addGenericListener(priority: EventPriority, consumer: Consumer<T>) {
+ addGenericListener(F::class.java, priority, false, consumer)
+ }
+
+ /**
+ * Add a consumer listener with the specified [EventPriority] and potentially cancelled events,
+ * for a [GenericEvent] subclass, filtered to only be called for the specified
+ * filter [Class].
+ *
+ * @param genericClassFilter A [Class] which the [GenericEvent] should be filtered for
+ * @param priority [EventPriority] for this listener
+ * @param receiveCancelled Indicate if this listener should receive events that have been [Cancelable] cancelled
+ * @param consumer Callback to invoke when a matching event is received
+ * @param T The [GenericEvent] subclass to listen for
+ * @param F The [Class] to filter the [GenericEvent] for
+ */
+ public inline fun <T : GenericEvent<out F>, reified F> addGenericListener(priority: EventPriority, receiveCancelled: Boolean, consumer: Consumer<T>) {
+ addGenericListener(F::class.java, priority, receiveCancelled, consumer)
+ }
+
+ /**
* Add a consumer listener for a [GenericEvent] subclass, filtered to only be called for the specified
* filter [Class].
*
@@ -365,7 +396,7 @@ open class KotlinEventBus(builder: BusBuilder, synthetic: Boolean = false) : IEv
shutdown = false
}
- companion object {
+ private companion object {
private val LOGGER = LogManager.getLogger()
private val EVENT_BUS = MarkerManager.getMarker("EVENTBUS")
private val MAX_ID: AtomicInteger
diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/eventbus/KotlinEventBusWrapper.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/eventbus/KotlinEventBusWrapper.kt
index b3cb9d5..ac12b1b 100644
--- a/src/main/kotlin/thedarkcolour/kotlinforforge/eventbus/KotlinEventBusWrapper.kt
+++ b/src/main/kotlin/thedarkcolour/kotlinforforge/eventbus/KotlinEventBusWrapper.kt
@@ -12,40 +12,40 @@ import java.util.concurrent.ConcurrentHashMap
* Fixes [IEventBus.addListener] for Kotlin SAM interfaces
* when using [FORGE_BUS].
*/
-class KotlinEventBusWrapper(private val parent: EventBus) : KotlinEventBus(BusBuilder()
+public class KotlinEventBusWrapper(private val parent: EventBus) : KotlinEventBus(BusBuilder()
.setExceptionHandler(getExceptionHandler(parent))
.setTrackPhases(getTrackPhases(parent))
.also { if (getShutdown(parent)) it.startShutdown() }
) {
- override val busID = getBusID(parent)
- override val listeners = getListeners(parent)
+ override val busID: Int = getBusID(parent)
+ override val listeners: ConcurrentHashMap<Any, MutableList<IEventListener>> = getListeners(parent)
// reflection stuff
- companion object {
+ private companion object {
private val GET_BUS_ID = EventBus::class.java.getDeclaredField("busID").also { it.isAccessible = true }
private val GET_LISTENERS = EventBus::class.java.getDeclaredField("listeners").also { it.isAccessible = true }
private val GET_EXCEPTION_HANDLER = EventBus::class.java.getDeclaredField("exceptionHandler").also { it.isAccessible = true }
private val GET_TRACK_PHASES = EventBus::class.java.getDeclaredField("trackPhases").also { it.isAccessible = true }
private val GET_SHUTDOWN = EventBus::class.java.getDeclaredField("shutdown").also { it.isAccessible = true }
- fun getBusID(eventBus: EventBus): Int {
+ private fun getBusID(eventBus: EventBus): Int {
return GET_BUS_ID[eventBus] as Int
}
@Suppress("UNCHECKED_CAST")
- fun getListeners(eventBus: EventBus): ConcurrentHashMap<Any, MutableList<IEventListener>> {
+ private fun getListeners(eventBus: EventBus): ConcurrentHashMap<Any, MutableList<IEventListener>> {
return GET_LISTENERS[eventBus] as ConcurrentHashMap<Any, MutableList<IEventListener>>
}
- fun getExceptionHandler(eventBus: EventBus): IEventExceptionHandler {
+ private fun getExceptionHandler(eventBus: EventBus): IEventExceptionHandler {
return GET_EXCEPTION_HANDLER[eventBus] as IEventExceptionHandler
}
- fun getTrackPhases(eventBus: EventBus): Boolean {
+ private fun getTrackPhases(eventBus: EventBus): Boolean {
return GET_TRACK_PHASES[eventBus] as Boolean
}
- fun getShutdown(eventBus: EventBus): Boolean {
+ private fun getShutdown(eventBus: EventBus): Boolean {
return GET_SHUTDOWN[eventBus] as Boolean
}
}
diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt
index a792863..37cc207 100644
--- a/src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt
+++ b/src/main/kotlin/thedarkcolour/kotlinforforge/forge/Forge.kt
@@ -15,8 +15,10 @@ import thedarkcolour.kotlinforforge.KotlinModLoadingContext
import thedarkcolour.kotlinforforge.LOGGER
import thedarkcolour.kotlinforforge.eventbus.KotlinEventBus
import thedarkcolour.kotlinforforge.eventbus.KotlinEventBusWrapper
+import java.util.*
import java.util.function.Consumer
import java.util.function.Predicate
+import kotlin.collections.HashMap
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
@@ -34,11 +36,11 @@ import kotlin.reflect.KProperty
* @see net.minecraftforge.event.entity.living.LivingEvent
* @see net.minecraftforge.event.world.BlockEvent
*/
-val FORGE_BUS = KotlinEventBusWrapper(MinecraftForge.EVENT_BUS as EventBus)
+public val FORGE_BUS: KotlinEventBusWrapper = KotlinEventBusWrapper(MinecraftForge.EVENT_BUS as EventBus)
/** @since 1.0.0
* The mod-specific [EventBus].
- * Setup events are typically fired on this bus.
+ * Mod lifecycle events are fired on this bus.
*
* @since 1.2.0
* This event bus supports [EventBus.addListener]
@@ -50,7 +52,7 @@ val FORGE_BUS = KotlinEventBusWrapper(MinecraftForge.EVENT_BUS as EventBus)
* @see net.minecraftforge.event.AttachCapabilitiesEvent
* @see net.minecraftforge.event.RegistryEvent
*/
-val MOD_BUS: KotlinEventBus
+public val MOD_BUS: KotlinEventBus
inline get() = KotlinModLoadingContext.get().getKEventBus()
/** @since 1.0.0
@@ -58,22 +60,22 @@ val MOD_BUS: KotlinEventBus
*
* Used in place of [net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext]
*/
-val MOD_CONTEXT: KotlinModLoadingContext
+public val MOD_CONTEXT: KotlinModLoadingContext
inline get() = KotlinModLoadingContext.get()
-val LOADING_CONTEXT: ModLoadingContext
+public val LOADING_CONTEXT: ModLoadingContext
inline get() = ModLoadingContext.get()
/** @since 1.0.0
* The current [Dist] of this environment.
*/
-val DIST: Dist = FMLEnvironment.dist
+public val DIST: Dist = FMLEnvironment.dist
/** @since 1.2.2
* The instance of Minecraft.
* Make sure to only call this on the client side.
*/
-val MINECRAFT: Minecraft
+public val MINECRAFT: Minecraft
@OnlyIn(Dist.CLIENT)
inline get() = Minecraft.getInstance()
@@ -81,7 +83,7 @@ val MINECRAFT: Minecraft
* An alternative to [net.minecraftforge.fml.DistExecutor.callWhenOn]
* that inlines the callable.
*/
-inline fun <T> callWhenOn(dist: Dist, toRun: () -> T): T? {
+public inline fun <T> callWhenOn(dist: Dist, toRun: () -> T): T? {
return if (DIST == dist) {
try {
toRun()
@@ -97,7 +99,7 @@ inline fun <T> callWhenOn(dist: Dist, toRun: () -> T): T? {
* An alternative to [net.minecraftforge.fml.DistExecutor.runWhenOn]
* that inlines the runnable.
*/
-inline fun runWhenOn(dist: Dist, toRun: () -> Unit) {
+public inline fun runWhenOn(dist: Dist, toRun: () -> Unit) {
if (DIST == dist) {
toRun()
}
@@ -107,7 +109,7 @@ inline fun runWhenOn(dist: Dist, toRun: () -> Unit) {
* An alternative to [net.minecraftforge.fml.DistExecutor.runForDist]
* that inlines the function call.
*/
-inline fun <T> runForDist(clientTarget: () -> T, serverTarget: () -> T): T {
+public inline fun <T> runForDist(clientTarget: () -> T, serverTarget: () -> T): T {
return when (DIST) {
Dist.CLIENT -> clientTarget()
Dist.DEDICATED_SERVER -> serverTarget()
@@ -117,7 +119,7 @@ inline fun <T> runForDist(clientTarget: () -> T, serverTarget: () -> T): T {
/** @since 1.0.0
* Registers a config.
*/
-fun registerConfig(type: ModConfig.Type, spec: ForgeConfigSpec, fileName: String? = null) {
+public fun registerConfig(type: ModConfig.Type, spec: ForgeConfigSpec, fileName: String? = null) {
if (fileName == null) {
LOADING_CONTEXT.registerConfig(type, spec)
} else {
@@ -136,7 +138,7 @@ fun registerConfig(type: ModConfig.Type, spec: ForgeConfigSpec, fileName: String
*
* @see sidedDelegate if you'd like a sided value that is computed each time it is accessed
*/
-fun <T> lazySidedDelegate(clientValue: () -> T, serverValue: () -> T): ReadOnlyProperty<Any?, T> {
+public fun <T> lazySidedDelegate(clientValue: () -> T, serverValue: () -> T): ReadOnlyProperty<Any?, T> {
return LazySidedDelegate(clientValue, serverValue)
}
@@ -149,7 +151,7 @@ fun <T> lazySidedDelegate(clientValue: () -> T, serverValue: () -> T): ReadOnlyP
* @param serverValue the value of this property on the server side.
* @param T the common type of both values. It is recommended to not use [Any] when possible.
*/
-fun <T> sidedDelegate(clientValue: () -> T, serverValue: () -> T): ReadOnlyProperty<Any?, T> {
+public fun <T> sidedDelegate(clientValue: () -> T, serverValue: () -> T): ReadOnlyProperty<Any?, T> {
return SidedDelegate(clientValue, serverValue)
}
@@ -159,8 +161,8 @@ fun <T> sidedDelegate(clientValue: () -> T, serverValue: () -> T): ReadOnlyPrope
* This delegate serves as an alternative to using the
* `@ObjectHolder` annotation, making it easier to use in Kotlin.
*/
-inline fun <reified T : IForgeRegistryEntry<T>> objectHolder(registryName: ResourceLocation): ReadOnlyProperty<Any?, T> {
- return ObjectHolderDelegate(registryName, RegistryManager.ACTIVE.getRegistry(T::class.java) as ForgeRegistry<T>)
+public inline fun <reified T : IForgeRegistryEntry<in T>> objectHolder(registryName: ResourceLocation): ReadOnlyProperty<Any?, T> {
+ return ObjectHolderDelegate(registryName, ObjectHolderDelegate.getRegistry(T::class.java))
}
/** @since 1.2.2
@@ -170,10 +172,10 @@ inline fun <reified T : IForgeRegistryEntry<T>> objectHolder(registryName: Resou
* This delegate serves as an alternative to using the
* `@ObjectHolder` annotation, making it easier to use in Kotlin.
*/
-inline fun <reified T : IForgeRegistryEntry<T>> objectHolder(registryName: String): ReadOnlyProperty<Any?, T> {
+public inline fun <reified T : IForgeRegistryEntry<in T>> objectHolder(registryName: String): ReadOnlyProperty<Any?, T> {
return ObjectHolderDelegate(
registryName = GameData.checkPrefix(registryName, true),
- registry = RegistryManager.ACTIVE.getRegistry(T::class.java) as ForgeRegistry<T>
+ registry = ObjectHolderDelegate.getRegistry(T::class.java)
)
}
@@ -210,9 +212,13 @@ private class SidedDelegate<T>(private val clientValue: () -> T, private val ser
/** @since 1.2.2
* An alternative to the `@ObjectHolder` annotation.
*
- * This property delegate is for people who would like to avoid
+ * This property delegate is for those who would like to avoid
* using annotations all over their non-static Kotlin code.
*
+ * [ObjectHolderDelegate] delegates to a non-null
+ * `IForgeRegistryEntry` value with registry name [registryName]
+ * in an `IForgeRegistry` [registry] of type [T].
+ *
* This class has proper implementations of
* [copy], [hashCode], [equals], and [toString].
*
@@ -221,9 +227,9 @@ private class SidedDelegate<T>(private val clientValue: () -> T, private val ser
* @property registry the registry the object of this delegate is in
* @property value the current value of this object holder.
*/
-data class ObjectHolderDelegate<T : IForgeRegistryEntry<T>>(
+public data class ObjectHolderDelegate<T : IForgeRegistryEntry<in T>>(
private val registryName: ResourceLocation,
- private val registry: ForgeRegistry<T>,
+ private val registry: IForgeRegistry<*>,
) : ReadOnlyProperty<Any?, T>, Consumer<Predicate<ResourceLocation>> {
/**
* Should be initialized by [accept]. If you don't register
@@ -257,10 +263,45 @@ data class ObjectHolderDelegate<T : IForgeRegistryEntry<T>>(
val tempValue = registry.getValue(registryName)
if (tempValue != null) {
- value = tempValue
+ value = tempValue as T
} else {
LOGGER.debug("Unable to lookup value for $this, likely just mod options.")
}
}
}
+
+ public companion object {
+ private val TYPE_2_REGISTRY = HashMap<Class<*>, IForgeRegistry<*>>()
+
+ public fun getRegistry(clazz: Class<*>): IForgeRegistry<*> {
+ return TYPE_2_REGISTRY.computeIfAbsent(clazz, ::findRegistry)
+ }
+
+ private fun findRegistry(clazz: Class<*>): IForgeRegistry<*> {
+ val typeQueue = LinkedList<Class<*>>()
+ var registry: IForgeRegistry<*>? = null
+
+ typeQueue.add(clazz)
+
+ while (typeQueue.isNotEmpty() && registry == null) {
+ val type = typeQueue.remove()
+ typeQueue.addAll(type.interfaces)
+
+ if (IForgeRegistryEntry::class.java.isAssignableFrom(type)) {
+ registry = RegistryManager.ACTIVE.getRegistry(type)
+
+ val parent = type.superclass
+
+ if (parent != null) {
+ typeQueue.add(parent)
+ }
+ }
+ }
+
+ return registry ?: throw IllegalArgumentException(
+ "ObjectHolderDelegate must represent " +
+ "a type that implements IForgeRegistryEntry"
+ )
+ }
+ }
} \ No newline at end of file
diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/kotlin/Kotlin.kt b/src/main/kotlin/thedarkcolour/kotlinforforge/kotlin/Kotlin.kt
index faf4d20..5b60df2 100644
--- a/src/main/kotlin/thedarkcolour/kotlinforforge/kotlin/Kotlin.kt
+++ b/src/main/kotlin/thedarkcolour/kotlinforforge/kotlin/Kotlin.kt
@@ -6,14 +6,14 @@ import java.util.function.Supplier
/**
* Returns a supplier that always returns the same value.
*/
-inline fun <T> supply(value: T): Supplier<T> {
+public fun <T> supply(value: T): Supplier<T> {
return Supplier { value }
}
/**
* Returns an empty new [EnumMap].
*/
-inline fun <reified K : Enum<K>, V> enumMapOf(): MutableMap<K, V> {
+public inline fun <reified K : Enum<K>, V> enumMapOf(): MutableMap<K, V> {
return EnumMap(K::class.java)
}
@@ -21,14 +21,14 @@ inline fun <reified K : Enum<K>, V> enumMapOf(): MutableMap<K, V> {
* Returns an new [EnumMap] with the specified contents, given as a list of pairs
* where the first component is the key and the second is the value.
*/
-inline fun <reified K : Enum<K>, V> enumMapOf(vararg pairs: Pair<K, V>): MutableMap<K, V> {
+public inline fun <reified K : Enum<K>, V> enumMapOf(vararg pairs: Pair<K, V>): MutableMap<K, V> {
return EnumMap<K, V>(K::class.java).apply { putAll(pairs) }
}
/**
* Returns an empty [EnumSet] with the specified element type.
*/
-inline fun <reified E : Enum<E>> enumSet(): EnumSet<E> {
+public inline fun <reified E : Enum<E>> enumSet(): EnumSet<E> {
return EnumSet.noneOf(E::class.java)
}
@@ -41,35 +41,35 @@ inline fun <reified E : Enum<E>> enumSet(): EnumSet<E> {
* an enum set initially containing an arbitrary number of elements, but
* is likely to run slower than the overloads that do not use varargs.
*/
-inline fun <E : Enum<E>> enumSetOf(e: E): EnumSet<E> {
+public inline fun <E : Enum<E>> enumSetOf(e: E): EnumSet<E> {
return EnumSet.of(e)
}
/**
* @see enumSetOf
*/
-inline fun <E : Enum<E>> enumSetOf(e1: E, e2: E): EnumSet<E> {
+public inline fun <E : Enum<E>> enumSetOf(e1: E, e2: E): EnumSet<E> {
return EnumSet.of(e1, e2)
}
/**
* @see enumSetOf
*/
-inline fun <E : Enum<E>> enumSetOf(e1: E, e2: E, e3: E): EnumSet<E> {
+public inline fun <E : Enum<E>> enumSetOf(e1: E, e2: E, e3: E): EnumSet<E> {
return EnumSet.of(e1, e2, e3)
}
/**
* @see enumSetOf
*/
-inline fun <E : Enum<E>> enumSetOf(e1: E, e2: E, e3: E, e4: E): EnumSet<E> {
+public inline fun <E : Enum<E>> enumSetOf(e1: E, e2: E, e3: E, e4: E): EnumSet<E> {
return EnumSet.of(e1, e2, e3, e4)
}
/**
* @see enumSetOf
*/
-inline fun <E : Enum<E>> enumSetOf(e1: E, e2: E, e3: E, e4: E, e5: E): EnumSet<E> {
+public inline fun <E : Enum<E>> enumSetOf(e1: E, e2: E, e3: E, e4: E, e5: E): EnumSet<E> {
return EnumSet.of(e1, e2, e3, e4, e5)
}
@@ -80,6 +80,6 @@ inline fun <E : Enum<E>> enumSetOf(e1: E, e2: E, e3: E, e4: E, e5: E): EnumSet<E
* number of elements, but it is likely to run slower than the overloads
* that do not use varargs.
*/
-inline fun <E : Enum<E>> enumSetOf(first: E, vararg rest: E): EnumSet<E> {
+public inline fun <E : Enum<E>> enumSetOf(first: E, vararg rest: E): EnumSet<E> {
return EnumSet.of(first, *rest)
} \ No newline at end of file
diff --git a/src/main/kotlin/thedarkcolour/kotlinforforge/kotlin/package.md b/src/main/kotlin/thedarkcolour/kotlinforforge/kotlin/package.md
index 094648a..00b6268 100644
--- a/src/main/kotlin/thedarkcolour/kotlinforforge/kotlin/package.md
+++ b/src/main/kotlin/thedarkcolour/kotlinforforge/kotlin/package.md
@@ -1,6 +1,6 @@
# thedarkcolour.kotlinforforge.kotlin
Since 1.2.2, Kotlin for Forge includes a few extra functions for creating
-collections that are less common than those in ``Collections.kt``.
+collections that are used less often than those in ``Collections.kt``.
This package contains various utility functions that aren't really
related to Minecraft or Minecraft forge, but are still useful in some cases. \ No newline at end of file
diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml
index aab060a..aef9147 100644
--- a/src/main/resources/META-INF/mods.toml
+++ b/src/main/resources/META-INF/mods.toml
@@ -1,5 +1,5 @@
modLoader="kotlinforforge" # IModLanguageProvider
-loaderVersion="[1,)" # IModLanguageProvider version
+loaderVersion="[1.3,)" # IModLanguageProvider version
issueTrackerURL="https://github.com/thedarkcolour/Future-MC/issues" # Issues page
@@ -31,6 +31,6 @@ Kotlin for Forge. Allows mods to use the Kotlin programming language.
[[mods]] #mandatory
displayName="Kotlin for Forge" # Name of mod
modId="kotlinforforge" # Modid
-version="1.2.2" # Version of kotlinforforge
+version="1.3.0" # Version of kotlinforforge
authors="TheDarkColour" # Author
credits="Herobrine knows all." # Credits \ No newline at end of file
diff --git a/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0-sources.jar b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0-sources.jar
new file mode 100644
index 0000000..e5477d5
--- /dev/null
+++ b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0-sources.jar
Binary files differ
diff --git a/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0-sources.jar.md5 b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0-sources.jar.md5
new file mode 100644
index 0000000..c6b3b9e
--- /dev/null
+++ b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0-sources.jar.md5
@@ -0,0 +1 @@
+da41e55af9709623c8e70a8228619eea \ No newline at end of file
diff --git a/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0-sources.jar.sha1 b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0-sources.jar.sha1
new file mode 100644
index 0000000..97622b0
--- /dev/null
+++ b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0-sources.jar.sha1
@@ -0,0 +1 @@
+acc4d99ef3fb301a942dc201b812f3db09932363 \ No newline at end of file
diff --git a/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.jar b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.jar
new file mode 100644
index 0000000..0f719dc
--- /dev/null
+++ b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.jar
Binary files differ
diff --git a/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.jar.md5 b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.jar.md5
new file mode 100644
index 0000000..01fff24
--- /dev/null
+++ b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.jar.md5
@@ -0,0 +1 @@
+9f9589efad6b58b4784e97802fa95d12 \ No newline at end of file
diff --git a/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.jar.sha1 b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.jar.sha1
new file mode 100644
index 0000000..f2d1ad8
--- /dev/null
+++ b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.jar.sha1
@@ -0,0 +1 @@
+45612182c96c2512c1f2637de98907725deab9dc \ No newline at end of file
diff --git a/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.pom b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.pom
new file mode 100644
index 0000000..14a1e06
--- /dev/null
+++ b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.pom
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>thedarkcolour</groupId>
+ <artifactId>kotlinforforge</artifactId>
+ <version>1.3.0</version>
+ <repositories>
+ <repository>
+ <id>kt-eap</id>
+ <name>Kotlin Early Access</name>
+ <url>https://dl.bintray.com/kotlin/kotlin-eap</url>
+ </repository>
+ </repositories>
+ <dependencies>
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-stdlib</artifactId>
+ <version>1.4-M2</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-stdlib-jdk7</artifactId>
+ <version>1.4-M2</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-stdlib-jdk8</artifactId>
+ <version>1.4-M2</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlin</groupId>
+ <artifactId>kotlin-reflect</artifactId>
+ <version>1.4-M2</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains</groupId>
+ <artifactId>annotations</artifactId>
+ <version>19.0.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlinx</groupId>
+ <artifactId>kotlinx-coroutines-core</artifactId>
+ <version>1.3.7</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jetbrains.kotlinx</groupId>
+ <artifactId>kotlinx-coroutines-jdk8</artifactId>
+ <version>1.3.7</version>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project>
diff --git a/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.pom.md5 b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.pom.md5
new file mode 100644
index 0000000..64387ef
--- /dev/null
+++ b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.pom.md5
@@ -0,0 +1 @@
+6d39116e5821281212e6ebccdeb3306a \ No newline at end of file
diff --git a/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.pom.sha1 b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.pom.sha1
new file mode 100644
index 0000000..af7e2d1
--- /dev/null
+++ b/thedarkcolour/kotlinforforge/1.3.0/kotlinforforge-1.3.0.pom.sha1
@@ -0,0 +1 @@
+e4547e9ec0d90efebf162605051d3da26fe0bb6c \ No newline at end of file
diff --git a/thedarkcolour/kotlinforforge/1.3.0/web.html b/thedarkcolour/kotlinforforge/1.3.0/web.html
new file mode 100644
index 0000000..27e4bcf
--- /dev/null
+++ b/thedarkcolour/kotlinforforge/1.3.0/web.html
@@ -0,0 +1,20 @@
+<html lang="HTML5">
+<link rel="stylesheet" href="../../style.css">
+<head><title>Index of /1.3.0/</title></head>
+<body>
+<h1>Index of /kotlinforforge/</h1>
+<hr>
+<pre><a href="../web.html">../</a>
+<a href="kotlinforforge-1.3.0-sources.jar">kotlinforforge-1.3.0-sources.jar</a>
+<a href="kotlinforforge-1.3.0-sources.jar.sha1">kotlinforforge-1.3.0-sources.jar.sha1</a>
+<a href="kotlinforforge-1.3.0-sources.jar.md5">kotlinforforge-1.3.0-sources.jar.md5</a>
+<a href="kotlinforforge-1.3.0.jar">kotlinforforge-1.3.0.jar</a>
+<a href="kotlinforforge-1.3.0.jar.sha1">kotlinforforge-1.3.0.jar.sha1</a>
+<a href="kotlinforforge-1.3.0.jar.md5">kotlinforforge-1.3.0.jar.md5</a>
+<a href="kotlinforforge-1.3.0.pom">kotlinforforge-1.3.0.pom</a>
+<a href="kotlinforforge-1.3.0.pom.sha1">kotlinforforge-1.3.0.pom.sha1</a>
+<a href="kotlinforforge-1.3.0.pom.md5">kotlinforforge-1.3.0.pom.md5</a>
+</pre>
+<hr>
+</body>
+</html>
diff --git a/thedarkcolour/kotlinforforge/maven-metadata.xml b/thedarkcolour/kotlinforforge/maven-metadata.xml
index 193f821..a546dc5 100644
--- a/thedarkcolour/kotlinforforge/maven-metadata.xml
+++ b/thedarkcolour/kotlinforforge/maven-metadata.xml
@@ -3,13 +3,15 @@
<groupId>thedarkcolour</groupId>
<artifactId>kotlinforforge</artifactId>
<versioning>
- <release>1.2.1</release>
+ <release>1.3.0</release>
<versions>
<version>1.0.0</version>
<version>1.0.1</version>
<version>1.1.0</version>
<version>1.2.0</version>
<version>1.2.1</version>
+ <version>1.2.2</version>
+ <version>1.3.0</version>
</versions>
</versioning>
</metadata>
diff --git a/thedarkcolour/kotlinforforge/web.html b/thedarkcolour/kotlinforforge/web.html
index 3b3440c..b266fcf 100644
--- a/thedarkcolour/kotlinforforge/web.html
+++ b/thedarkcolour/kotlinforforge/web.html
@@ -14,6 +14,7 @@
<a href="1.2.0/web.html">1.2.0</a>
<a href="1.2.1/web.html">1.2.1</a>
<a href="1.2.2/web.html">1.2.2</a>
+<a href="1.3.0/web.html">1.3.0</a>
<a href="maven-metadata.xml">maven-metadata.xml</a>
<a href="maven-metadata.xml.md5">maven-metadata.xml.md5</a>
<a href="maven-metadata.xml.sha1">maven-metadata.xml.sha1</a>