Merge remote-tracking branch 'origin/main'

# Conflicts:
#	gradle/libs.versions.toml
This commit is contained in:
Adam 2022-12-28 22:16:27 +01:00
commit 8281821075
76 changed files with 1100 additions and 4655 deletions

View file

@ -38,8 +38,8 @@ idea {
} }
tasks.wrapper { tasks.wrapper {
gradleVersion = "7.5.1" gradleVersion = "7.6"
distributionType = Wrapper.DistributionType.ALL distributionType = Wrapper.DistributionType.BIN
} }
val runKafkatorio by tasks.registering { val runKafkatorio by tasks.registering {

View file

@ -17,9 +17,9 @@ plugins {
dependencies { dependencies {
implementation(platform(libs.kotlin.bom)) implementation(platform(libs.kotlin.bom))
implementation("org.jetbrains.kotlin:kotlin-serialization") implementation("org.jetbrains.kotlin:kotlin-serialization:${libs.versions.kotlin.get()}")
implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-reflect:${libs.versions.kotlin.get()}")
implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${libs.versions.kotlin.get()}")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}")
implementation(platform(libs.kotlinx.coroutines.bom)) implementation(platform(libs.kotlinx.coroutines.bom))

View file

@ -2,40 +2,32 @@ package kafkatorio.tasks
import com.github.gradle.node.npm.task.NpmTask import com.github.gradle.node.npm.task.NpmTask
import javax.inject.Inject import javax.inject.Inject
import org.gradle.api.file.ConfigurableFileTree import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileSystemOperations import org.gradle.api.file.FileSystemOperations
import org.gradle.api.plugins.BasePlugin import org.gradle.api.plugins.BasePlugin
import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.*
import org.gradle.api.tasks.IgnoreEmptyDirectories
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.SkipWhenEmpty
import org.gradle.api.tasks.TaskAction
import org.gradle.work.NormalizeLineEndings import org.gradle.work.NormalizeLineEndings
import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs
@CacheableTask @CacheableTask
abstract class TypescriptToLuaTask @Inject constructor( abstract class TypeScriptToLuaTask @Inject constructor(
private val fs: FileSystemOperations private val fs: FileSystemOperations
) : NpmTask() { ) : NpmTask() {
@get:InputDirectory @get:InputFiles
@get:SkipWhenEmpty @get:SkipWhenEmpty
@get:PathSensitive(PathSensitivity.RELATIVE) @get:PathSensitive(PathSensitivity.RELATIVE)
@get:NormalizeLineEndings @get:NormalizeLineEndings
@get:IgnoreEmptyDirectories @get:IgnoreEmptyDirectories
abstract val sourceFiles: DirectoryProperty abstract val sourceFiles: ConfigurableFileCollection
@get:OutputDirectory @get:OutputDirectory
abstract val outputDirectory: DirectoryProperty abstract val outputDirectory: DirectoryProperty
init { init {
super.setGroup(BasePlugin.BUILD_GROUP) super.setGroup(BasePlugin.BUILD_GROUP)
super.setDescription("Convert Typescript To Lua") super.setDescription("Convert TypeScript To Lua")
super.execOverrides { standardOutput = System.out } super.execOverrides { standardOutput = System.out }
super.npmCommand.set(listOf("run", "build")) super.npmCommand.set(listOf("run", "build"))
super.ignoreExitValue.set(false) super.ignoreExitValue.set(false)

View file

@ -5,7 +5,7 @@ plugins {
dependencies { dependencies {
implementation(platform(libs.kotlin.bom)) implementation(platform(libs.kotlin.bom))
implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable") implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${libs.versions.kotlin.get()}")
} }
gradlePlugin { gradlePlugin {

View file

@ -25,6 +25,7 @@ abstract class DockerEnvUpdateTask @Inject constructor(
) : DefaultTask() { ) : DefaultTask() {
@get:Input @get:Input
@get:Optional
abstract val envProperties: MapProperty<String, String> abstract val envProperties: MapProperty<String, String>
@get:Input @get:Input
@ -50,10 +51,11 @@ abstract class DockerEnvUpdateTask @Inject constructor(
val comment: String = comment.orNull val comment: String = comment.orNull
?: " Do not edit manually. This file was created with task '$name'" ?: " Do not edit manually. This file was created with task '$name'"
val envProperties = envProperties.getOrElse(emptyMap())
dotEnvFile.writer(charset).use { writer -> dotEnvFile.writer(charset).use { writer ->
val properties = Properties() val properties = Properties()
properties.putAll(envProperties.get()) properties.putAll(envProperties)
properties.store(writer, comment) properties.store(writer, comment)
} }

View file

@ -31,6 +31,8 @@ dependencies {
implementation(libs.ktorClient.cio) implementation(libs.ktorClient.cio)
implementation(libs.ktorClient.resources) implementation(libs.ktorClient.resources)
implementation(libs.ktorSerialization.kotlinxJson) implementation(libs.ktorSerialization.kotlinxJson)
implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${libs.versions.kotlin.get()}")
} }
gradlePlugin { gradlePlugin {
@ -41,6 +43,13 @@ gradlePlugin {
implementationClass = "dev.adamko.gradle.factorio.FactorioModPlugin" implementationClass = "dev.adamko.gradle.factorio.FactorioModPlugin"
} }
} }
plugins {
create("factorioModLibrary") {
displayName = "Factorio Mod Library"
id = "dev.adamko.factorio-mod-library"
implementationClass = "dev.adamko.gradle.factorio.FactorioModLibraryPlugin"
}
}
} }
overrideKotlinLanguageVersion("1.7") // required for Kotlinx Serialization overrideKotlinLanguageVersion("1.7") // required for Kotlinx Serialization

View file

@ -0,0 +1,9 @@
package dev.adamko.gradle.factorio
import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.artifacts.Configuration
internal data class FactorioModConfigurations(
val factorioMod: NamedDomainObjectProvider<Configuration>,
val factorioModProvider: NamedDomainObjectProvider<Configuration>,
)

View file

@ -1,43 +0,0 @@
package dev.adamko.gradle.factorio
import javax.inject.Inject
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.internal.file.FileOperations
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
abstract class FactorioModInstallTask @Inject constructor(
private val files: FileSystemOperations,
) : DefaultTask() {
@get:Internal
abstract val clientModDirectory: DirectoryProperty
@get:InputFiles
abstract val modFiles: ConfigurableFileCollection
init {
description = "Copy the mod to the Factorio client"
group = FactorioModPlugin.TASK_GROUP
super.onlyIf {
require(it is FactorioModInstallTask)
it.clientModDirectory.asFile.get().exists()
}
}
@TaskAction
fun install() {
logger.lifecycle("Copying mod from $modFiles to $clientModDirectory")
files.copy {
from(modFiles)
into(clientModDirectory)
}
}
}

View file

@ -0,0 +1,48 @@
package dev.adamko.gradle.factorio
import javax.inject.Inject
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.slf4j.LoggerFactory
/**
* Configure a [Project] to produce components that will be used in a Factorio mod, but no tasks
* that will create a Factorio mod.
*/
abstract class FactorioModLibraryPlugin @Inject constructor(
// private val objects: ObjectFactory,
// private val providers: ProviderFactory,
// private val layout: ProjectLayout,
// private val files: FileSystemOperations,
) : Plugin<Project> {
internal val logger = LoggerFactory.getLogger(this::class.java)
internal var factorioModConfigurations: FactorioModConfigurations? = null
private set
override fun apply(target: Project) {
factorioModConfigurations = target.createConfigurations()
}
private fun Project.createConfigurations(): FactorioModConfigurations {
return FactorioModConfigurations(
factorioMod = project.configurations.register(CONFIGURATION_NAME__FACTORIO_MOD) {
asConsumer()
factorioModAttributes(objects)
},
factorioModProvider = project.configurations.register(
CONFIGURATION_NAME__FACTORIO_MOD_PROVIDER
) {
asProvider()
factorioModAttributes(objects)
},
)
}
companion object {
const val CONFIGURATION_NAME__FACTORIO_MOD = "factorioMod"
const val CONFIGURATION_NAME__FACTORIO_MOD_PROVIDER = "factorioModProvider"
}
}

View file

@ -1,37 +1,104 @@
package dev.adamko.gradle.factorio package dev.adamko.gradle.factorio
import dev.adamko.gradle.factorio.tasks.AssembleFactorioModContents
import dev.adamko.gradle.factorio.tasks.GenerateFactorioModInfoTask
import dev.adamko.gradle.factorio.tasks.LaunchFactorioClientTask
import dev.adamko.gradle.factorio.tasks.LocalPublishFactorioModTask
import dev.adamko.gradle.factorio.tasks.PackageFactorioModTask
import javax.inject.Inject import javax.inject.Inject
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.file.ProjectLayout
import org.gradle.api.model.ObjectFactory import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ProviderFactory
import org.gradle.api.tasks.TaskProvider
import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.newInstance
import org.gradle.kotlin.dsl.register
import org.slf4j.LoggerFactory
abstract class FactorioModPlugin @Inject constructor( abstract class FactorioModPlugin @Inject constructor(
private val objects: ObjectFactory, private val objects: ObjectFactory,
private val providers: ProviderFactory,
private val layout: ProjectLayout,
private val files: FileSystemOperations,
) : Plugin<Project> { ) : Plugin<Project> {
internal val logger = LoggerFactory.getLogger(this::class.java)
override fun apply(target: Project) { override fun apply(target: Project) {
target.createSettings()
val factorioModConfiguration = val settings = target.extensions.create<FactorioModSettings>(FACTORIO_GRADLE_EXTENSION_NAME)
target.configurations.register(FACTORIO_GRADLE_CONFIGURATION_NAME) {
asConsumer() val factorioModLibraryPlugin = objects.newInstance<FactorioModLibraryPlugin>()
factorioModAttributes(objects) factorioModLibraryPlugin.apply(target)
} val factorioModConfigurations = factorioModLibraryPlugin.factorioModConfigurations
?: error("Could not create Factorio Mod Configurations")
val context = PluginContext(
target,
settings,
target.createTasks(),
factorioModConfigurations,
objects,
providers,
layout,
files,
)
context.configureModSettings()
context.configureTasks()
context.configureIdea()
// context.configureDistribution()
} }
private fun Project.createSettings(): FactorioModSettings { private fun Project.createTasks(): PluginContext.Tasks {
return extensions.create<FactorioModSettings>(FACTORIO_GRADLE_EXTENSION_NAME).apply { return PluginContext.Tasks(
launchFactorioClient = project.tasks.register<LaunchFactorioClientTask>("launchFactorioClient"),
assembleModContents = project.tasks.register<AssembleFactorioModContents>("assembleFactorioModContents"),
packageMod = project.tasks.register<PackageFactorioModTask>("packageFactorioMod"),
publishModToLocalClient = project.tasks.register<LocalPublishFactorioModTask>("publishFactorioModToLocalClient"),
generateModInfoJson = project.tasks.register<GenerateFactorioModInfoTask>("generateFactorioModInfoJson"),
)
}
internal class PluginContext(
val project: Project,
val settings: FactorioModSettings,
val tasks: Tasks,
val configurations: FactorioModConfigurations,
val objects: ObjectFactory,
val providers: ProviderFactory,
val layout: ProjectLayout,
val files: FileSystemOperations,
) {
internal val logger = LoggerFactory.getLogger(this::class.java)
data class Tasks(
val launchFactorioClient: TaskProvider<LaunchFactorioClientTask>,
val assembleModContents: TaskProvider<AssembleFactorioModContents>,
val packageMod: TaskProvider<PackageFactorioModTask>,
val publishModToLocalClient: TaskProvider<LocalPublishFactorioModTask>,
val generateModInfoJson: TaskProvider<GenerateFactorioModInfoTask>,
)
} }
}
companion object { companion object {
const val FACTORIO_GRADLE_EXTENSION_NAME = "factorioMod" const val FACTORIO_GRADLE_EXTENSION_NAME = "factorioMod"
const val FACTORIO_GRADLE_CONFIGURATION_NAME = "factorioMod"
const val TASK_GROUP = "factorioMod" const val CONFIGURATION_NAME__FACTORIO_MOD = "factorioMod"
const val CONFIGURATION_NAME__FACTORIO_MOD_PROVIDER = "factorioModProvider"
const val TASK_GROUP = "factorio mod"
/** Lifecycle task for publishing the mod locally */ /** Lifecycle task for publishing the mod locally */
const val PUBLISH_MOD_LOCAL_TASK_NAME = "publishModLocal" const val PUBLISH_MOD_LOCAL_TASK_NAME = "publishModLocal"

View file

@ -1,16 +1,69 @@
package dev.adamko.gradle.factorio package dev.adamko.gradle.factorio
import javax.inject.Inject
import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.ProjectLayout
import org.gradle.api.file.RegularFileProperty import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property import org.gradle.api.provider.Property
import org.gradle.api.provider.ProviderFactory
import org.gradle.kotlin.dsl.newInstance
interface FactorioModSettings { abstract class FactorioModSettings @Inject constructor(
internal val objects: ObjectFactory,
internal val providers: ProviderFactory,
internal val layout: ProjectLayout,
) {
val factorioClientModsDirectory: DirectoryProperty abstract val modName: Property<String>
abstract val modTitle: Property<String>
abstract val modDescription: Property<String>
abstract val modAuthor: Property<String>
abstract val modVersion: Property<String>
abstract val modDependencies: ListProperty<String>
val steamExe: RegularFileProperty // version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error)
abstract val factorioCompatibility: Property<String>
val factorioGameSteamId: Property<String> abstract val distributionZipName: Property<String>
val factorioServerDataDirectory: DirectoryProperty val mainSources: FactorioModSourceSet.WithResources = objects.newInstance("Main")
val testSources: FactorioModSourceSet.WithResources = objects.newInstance("Test")
val generatedSources: FactorioModSourceSet = objects.newInstance("Generated")
// abstract val typescriptSrcDir: DirectoryProperty
// abstract val resourcesDir: DirectoryProperty
// abstract val modDataResourcesDir: DirectoryProperty
// abstract val generatedLuaSrcDir: DirectoryProperty
abstract val factorioServerDataDirectory: DirectoryProperty
val localDev: LocalDev = objects.newInstance()
fun localDev(configure: LocalDev.() -> Unit) {
localDev.configure()
}
interface LocalDev {
val currentOs: Property<OS>
val windowsSteamExe: Property<String>
val factorioSteamId: Property<String>
val serverConnectHost: Property<String>
val clientModsDirectory: RegularFileProperty
val macApplicationSupportDir: RegularFileProperty
val macFactorioApp: RegularFileProperty
/** Supported local dev OSes */
enum class OS { WINDOWS, MAC_OS, UNSUPPORTED }
}
} }

View file

@ -0,0 +1,38 @@
package dev.adamko.gradle.factorio
import javax.inject.Inject
import org.gradle.api.Named
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.model.ObjectFactory
abstract class FactorioModSourceSet @Inject constructor(
private val named: String,
objects: ObjectFactory,
) : Named {
val typescript: SourceDirectorySet = objects
.sourceDirectorySet("ts${named}", "TypeScript $named source files")
.apply {
include("**/*.d.ts", "**/*.ts")
}
val lua: SourceDirectorySet = objects
.sourceDirectorySet("lua${named}", "Lua $named source files")
.apply {
include("**/*.lua")
}
override fun getName(): String = named
abstract class WithResources @Inject constructor(
type: String,
objects: ObjectFactory,
) : FactorioModSourceSet(type, objects) {
val resources: SourceDirectorySet = objects
.sourceDirectorySet("resources${type}", "$type resources")
.apply {
exclude("**/*.d.ts", "**/*.ts", "**/*.lua")
}
}
}

View file

@ -12,15 +12,15 @@ import org.gradle.api.model.ObjectFactory
import org.gradle.kotlin.dsl.named import org.gradle.kotlin.dsl.named
fun Configuration.asProvider() { fun Configuration.asProvider(visible: Boolean = false) {
isVisible = false isVisible = visible
isCanBeResolved = false isCanBeResolved = false
isCanBeConsumed = true isCanBeConsumed = true
} }
fun Configuration.asConsumer() { fun Configuration.asConsumer(visible: Boolean = false) {
isVisible = false isVisible = visible
isCanBeResolved = true isCanBeResolved = true
isCanBeConsumed = false isCanBeConsumed = false
} }

View file

@ -0,0 +1,42 @@
package dev.adamko.gradle.factorio
import org.gradle.api.distribution.DistributionContainer
import org.gradle.api.distribution.plugins.DistributionPlugin
import org.gradle.api.tasks.bundling.Zip
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.named
internal fun FactorioModPlugin.PluginContext.configureDistribution() {
project.plugins.apply(DistributionPlugin::class)
val distributions = project.extensions.getByType<DistributionContainer>()
distributions.named(DistributionPlugin.MAIN_DISTRIBUTION_NAME) {
distributionBaseName.set(settings.modName)
contents {
includeEmptyDirs = false
from(settings.mainSources.resources) {
include("**/**")
}
exclude {
// exclude empty files
it.file.run {
isFile && useLines { lines -> lines.all { line -> line.isBlank() } }
}
}
}
}
val distZipTask = project.tasks.named<Zip>("distZip")
configurations.factorioModProvider.configure {
outgoing.artifact(distZipTask.flatMap { it.archiveFile })
}
}

View file

@ -0,0 +1,38 @@
package dev.adamko.gradle.factorio
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.withType
import org.gradle.plugins.ide.idea.IdeaPlugin
import org.gradle.plugins.ide.idea.model.IdeaModel
//import org.gradle.plugins.ide.idea.model.Module as IdeaModule
internal fun FactorioModPlugin.PluginContext.configureIdea() {
project.plugins.withType<IdeaPlugin>().configureEach {
project.extensions.configure<IdeaModel> {
module {
// scopes["MAIN"] = mapOf("plus" to listOf(configurations.factorioMod.get()))
sourceDirs.plusAssign(settings.mainSources.typescript.srcDirs)
sourceDirs.plusAssign(settings.mainSources.lua.srcDirs)
sourceDirs.plusAssign(settings.generatedSources.lua.srcDirs)
testSources.from(settings.testSources.typescript)
testSources.from(settings.testSources.lua)
resourceDirs.plusAssign(settings.mainSources.resources.srcDirs)
testResources.from(settings.testSources.resources)
generatedSourceDirs.plusAssign(settings.generatedSources.lua.srcDirs)
generatedSourceDirs.plusAssign(settings.generatedSources.typescript.srcDirs)
// iml {
// whenMerged {
// require(this is IdeaModule)
//
// }
// }
}
}
}
}

View file

@ -0,0 +1,99 @@
package dev.adamko.gradle.factorio
import dev.adamko.gradle.factorio.FactorioModSettings.LocalDev.OS
import java.io.File
import org.gradle.api.internal.provider.Providers
import org.gradle.api.provider.ProviderFactory
internal fun FactorioModPlugin.PluginContext.configureModSettings() = with(settings) {
modName.convention(providers.provider { project.name })
modTitle.convention(modName)
modDescription.convention(providers.provider { project.description ?: "" })
modVersion.convention(providers.provider { project.version.toString() })
distributionZipName.convention(providers.zip(modName, modVersion) { name, version ->
"${name}_${version}.zip"
})
val srcBaseMain = layout.projectDirectory.dir("src/main")
mainSources.lua.srcDir(srcBaseMain.dir("lua"))
mainSources.typescript.srcDir(srcBaseMain.dir("typescript"))
mainSources.resources.srcDir(srcBaseMain.dir("resources"))
val srcBaseTest = layout.projectDirectory.dir("src/test")
testSources.lua.srcDir(srcBaseTest.dir("lua"))
testSources.typescript.srcDir(srcBaseTest.dir("typescript"))
testSources.resources.srcDir(srcBaseTest.dir("resources"))
val srcBaseGenerated = layout.buildDirectory.dir("generated-src").get()
generatedSources.lua.srcDir(srcBaseGenerated.dir("lua"))
generatedSources.typescript.srcDir(srcBaseGenerated.dir("typescript"))
mainSources.typescript.destinationDirectory.convention(srcBaseGenerated.dir("lua"))
configureLocalDev()
}
private fun FactorioModPlugin.PluginContext.configureLocalDev() = with(settings) {
val userHome = providers.systemProperty("user.home")
.map { home -> File(home) }
localDev {
currentOs.convention(providers.systemProperty("os.name").map { osName ->
val currentOS = osName.lowercase()
when {
"windows" in currentOS -> OS.WINDOWS
"mac" in currentOS -> OS.MAC_OS
else -> {
logger.warn("cannot select OS for Factorio local dev - '${osName}' is unsupported")
OS.UNSUPPORTED
}
}
})
windowsSteamExe.convention("""C:\Program Files (x86)\Steam\steam.exe""")
factorioSteamId.convention("427520")
// serverConnectHost.convention("localhost")
macApplicationSupportDir.convention(layout.file(userHome.map { home ->
home.resolve("""Library/Application Support/""")
}))
macFactorioApp.convention(layout.file(macApplicationSupportDir.map { appSupport ->
appSupport.asFile.resolve("""Steam/steamapps/common/Factorio/factorio.app/Contents/MacOS/factorio""")
}))
clientModsDirectory.convention(layout.file(
currentOs.flatMap { os ->
when (os) {
OS.WINDOWS -> userHome.map { home ->
home.resolve("""AppData/Roaming/Factorio/mods""")
}
OS.MAC_OS -> macApplicationSupportDir.map { appSupport ->
appSupport.asFile.resolve("""factorio/mods""")
}
OS.UNSUPPORTED -> {
logger.warn("cannot automatically determine Factorio client mod directory, $os is unsupported")
Providers.notDefined() // https://github.com/gradle/gradle/issues/12388
}
}
}
))
}
}
private fun ProviderFactory.factorioModProp(name: String) {
environmentVariable("FACTORIO_MOD_$name")
.orElse(gradleProperty("factorioMod_$name"))
}

View file

@ -0,0 +1,137 @@
package dev.adamko.gradle.factorio
import dev.adamko.gradle.factorio.tasks.AssembleFactorioModContents
import dev.adamko.gradle.factorio.tasks.GenerateFactorioModInfoTask
import dev.adamko.gradle.factorio.tasks.LaunchFactorioClientTask
import dev.adamko.gradle.factorio.tasks.LocalPublishFactorioModTask
import dev.adamko.gradle.factorio.tasks.PackageFactorioModTask
import org.gradle.kotlin.dsl.withType
internal fun FactorioModPlugin.PluginContext.configureTasks() {
tasks.launchFactorioClient.configure {
}
tasks.assembleModContents.configure {
modFiles.apply {
from(settings.mainSources.typescript.destinationDirectory)
from(tasks.generateModInfoJson)
from(settings.mainSources.resources)
}
}
tasks.packageMod.configure {
from(tasks.assembleModContents)
}
tasks.publishModToLocalClient.configure {
dependsOn(tasks.packageMod)
}
tasks.generateModInfoJson.configure {
}
project.tasks.withType<LocalPublishFactorioModTask>().configureEach {
description = "Copy the mod to the Factorio client"
group = FactorioModPlugin.TASK_GROUP
onlyIf {
require(it is LocalPublishFactorioModTask)
it.clientModDirectory.asFile.get().exists()
}
modFiles.from(
configurations.factorioMod.map {
it.incoming
.artifactView { lenient(true) }
.files
}
)
doLast {
logger.lifecycle("Published Factorio Mod to '${clientModDirectory.asFile.get()}'")
}
}
configureLaunchFactorioClientTasks()
project.tasks.withType<GenerateFactorioModInfoTask>().configureEach {
description = "Generate info.json (required for Factorio Mods)"
group = FactorioModPlugin.TASK_GROUP
modName.convention(settings.modName)
modTitle.convention(settings.modTitle)
modDescription.convention(settings.modDescription)
modAuthor.convention(settings.modAuthor)
modVersion.convention(settings.modVersion)
factorioCompatibility.convention(settings.factorioCompatibility)
modDependencies.convention(settings.modDependencies)
infoJson.convention(
layout.file(
providers.provider {
temporaryDir.resolve("info.json")
}
)
)
}
project.tasks.withType<AssembleFactorioModContents>().configureEach {
description = "Gather the mod files that will be packaged into the mod zip"
group = FactorioModPlugin.TASK_GROUP
modName.convention(settings.modName)
modVersion.convention(settings.modVersion)
destination.convention(layout.dir(providers.provider { temporaryDir }))
}
project.tasks.withType<PackageFactorioModTask>().configureEach {
description = "Package the Factorio mod"
group = FactorioModPlugin.TASK_GROUP
archiveFileName.convention(settings.distributionZipName)
includeEmptyDirs = false
exclude {
// exclude empty files
it.file.run {
isFile && useLines { lines -> lines.all { line -> line.isBlank() } }
}
}
}
project.tasks.withType<LocalPublishFactorioModTask>().configureEach {
description = "Launch local Factorio Steam game client"
group = FactorioModPlugin.TASK_GROUP
modFiles.from(project.tasks.withType<PackageFactorioModTask>())
clientModDirectory.convention(layout.dir(settings.localDev.clientModsDirectory.asFile))
}
}
private fun FactorioModPlugin.PluginContext.configureLaunchFactorioClientTasks() {
val localDev = settings.localDev
// // convert to local props -> try to comply with Gradle config cache
// val localDevCurrentOs = localDev.currentOs
// val localDevWindowsSteamExe = localDev.windowsSteamExe
// val localDevFactorioSteamId = localDev.factorioSteamId
// val localDevServerConnectHost = localDev.serverConnectHost
// val localDevClientModDirectory = localDev.clientModDirectory
// val localDevMacApplicationSupportDir = localDev.macApplicationSupportDir
// val localDevMacFactorioApp = localDev.macFactorioApp
project.tasks.withType<LaunchFactorioClientTask>().configureEach {
description = "Launch local Factorio Steam game client"
group = FactorioModPlugin.TASK_GROUP
currentOs.convention(localDev.currentOs)
windowsSteamExe.convention(localDev.windowsSteamExe)
factorioSteamId.convention(localDev.factorioSteamId)
serverConnectHost.convention(localDev.serverConnectHost)
clientModsPath.convention(localDev.clientModsDirectory.map { it.asFile.canonicalPath })
macFactorioApp.convention(localDev.macFactorioApp)
}
}

View file

@ -0,0 +1,19 @@
package dev.adamko.gradle.factorio.mod
// to be used in a NamedDomainObject container?
//import org.gradle.api.Named
//import org.gradle.api.provider.Property
//
//abstract class FactorioModProperties : Named {
//
// abstract val modName: Property<String>
// abstract val modTitle: Property<String>
// abstract val modDescription: Property<String>
// abstract val modVersion: Property<String>
//
// // version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error)
// abstract val factorioCompatibility: Property<String>
//
// abstract val distributionZipName: Property<String>
//}

View file

@ -69,8 +69,7 @@ class FactorioModPortalPublishClient(
client().useToRun { client().useToRun {
val initUploadResponse = initUpload() val initUploadResponse = initUpload()
val enteredVersion = userInputHandler val enteredVersion = userInputHandler.askQuestion(
.askQuestion(
""" """
|Are you sure you want to publish $modName:$modVersion? |Are you sure you want to publish $modName:$modVersion?
|Enter the version number to confirm: |Enter the version number to confirm:

View file

@ -0,0 +1,40 @@
package dev.adamko.gradle.factorio.tasks
import javax.inject.Inject
import org.gradle.api.*
import org.gradle.api.file.*
import org.gradle.api.internal.file.*
import org.gradle.api.provider.Property
import org.gradle.api.tasks.*
abstract class AssembleFactorioModContents @Inject constructor(
private val files: FileSystemOperations,
) : DefaultTask() {
@get:Input
abstract val modName: Property<String>
@get:Input
abstract val modVersion: Property<String>
@get:InputFiles
@get:SkipWhenEmpty
@get:PathSensitive(PathSensitivity.NAME_ONLY)
@get:IgnoreEmptyDirectories
abstract val modFiles: ConfigurableFileCollection
@get:OutputDirectory
abstract val destination: DirectoryProperty
@TaskAction
fun assemble() {
val modName = modName.get()
val modVersion = modVersion.get()
val modDirectory = "${modName}_${modVersion}"
files.sync {
from(modFiles)
into(destination.dir(modDirectory))
}
}
}

View file

@ -0,0 +1,132 @@
package dev.adamko.gradle.factorio.tasks
import javax.inject.Inject
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
abstract class GenerateFactorioModInfoTask @Inject constructor(
) : DefaultTask() {
/**
* Mandatory field. The internal name of mod. The game accepts anything as a mod name, however the mod portal restricts mod names to only consist of alphanumeric characters, dashes and underscores. Note that the mod folder or mod zip file name has to contain the mod name, where the restrictions of the file system apply.
*
* The game accepts mod names with a maximum length of 100 characters. The mod portal only accepts mods with names that are longer than 3 characters and shorter than 50 characters.
*/
@get:Input
abstract val modName: Property<String>
/**
* Mandatory field. The display name of the mod, so it is not recommended to use someUgly_pRoGrAmMeR-name here. Can be overwritten with a locale entry in the mod-name category, using the internal mod name as the key.
*
* The game will reject a title field that is longer than 100 characters. However, this can be worked around by using the locale entry. The mod portal does not restrict mod title length.
*/
@get:Input
abstract val modTitle: Property<String>
/**
* Optional field. A short description of what your mod does. This is all that people get to see in-game. Can be overwritten with a locale entry in the mod-description category, using the internal mod name as the key.
*/
@get:Input
@get:Optional
abstract val modDescription: Property<String>
/**
* Optional field. Where the mod can be found on the internet. Note that the in-game mod browser shows the mod portal link additionally to this field. Please don't put "None" here, it makes the field on the mod portal website look ugly. Just leave the field empty if the mod doesn't have a website/forum thread/discord.
*/
@get:Input
@get:Optional
abstract val modHomepage: Property<String>
/**
* Mandatory field. The author of the mod. This field does not have restrictions, it can also be a list of authors etc. The mod portal ignores this field, it will simply display the uploader's name as the author.
*/
@get:Input
abstract val modAuthor: Property<String>
/**
* Mandatory field. Defines the version of the mod in the format `number.number.number` for `Major.Middle.Minor`, for example `0.6.4`. Each number can range from 0 to 65535.
*/
@get:Input
abstract val modVersion: Property<String>
/**
* Optional field in the format "major.minor". The Factorio version that this mod supports. This can only be one Factorio version, not multiple. However, it includes all .sub versions. While the field is optional, usually mods are developed for versions higher than the default 0.12, so the field has to be added anyway.
*
* Adding a sub part, e.g. "0.18.27" will make the mod portal reject the mod and the game act weirdly. That means this shouldn't be done; use only the major and minor components "major.minor", for example "1.0".
*
* Mods with the factorio_version "0.18" can also be loaded in 1.0 and the mod portal will return them when queried for factorio_version 1.0 mods.
*/
@get:Input
@get:Optional
abstract val factorioCompatibility: Property<String>
/**
* Optional field. Mods that this mod depends on or is incompatible with.
* If this mod depends on another, the other mod will load first, see Data-Lifecycle.
* An empty array allows get around the default and have no dependencies at all.
*
* Example:
*
* `"dependencies": ["mod-a", "? mod-c > 0.4.3", "! mod-g"]`
*
* Each dependency is a string that consists of up to three parts: `<prefix> internal-mod-name <equality-operator version>`, for example `? some-mod-everyone-loves >= 4.2.0`.
*
* The equality operator (`<`, `<=`, `=`, `>=` or `>`) combined with the version allows to define dependencies that require certain mod versions, but it is not required.
*
* Incompatibility does not support versions; if incompatibility is used, version is ignored.
*
* The possible prefixes are:
* * `!` for incompatibility
* * `?` for an optional dependency
* * `(?)` for a hidden optional dependency
* * `~` for a dependency that does not affect load order
* * no prefix for a hard requirement for the other mod.
*/
@get:Input
@get:Optional
abstract val modDependencies: ListProperty<String>
@get:OutputFile
abstract val infoJson: RegularFileProperty
@TaskAction
fun generate() {
val infoJsonObject = buildJsonObject {
put("name", modName.get())
put("title", modTitle.get())
put("version", modVersion.get())
put("author", modAuthor.get())
modDescription.orNull?.let { put("description", it) }
modHomepage.orNull?.let { put("homepage", it) }
factorioCompatibility.orNull?.let { put("factorio_version", it) }
modDependencies.orNull?.let {
putJsonArray("dependencies") { it.forEach(::add) }
}
}
val infoJsonContent = encoder.encodeToString(infoJsonObject)
.replace("[\n ]", "[]")
val infoJson = infoJson.get().asFile
infoJson.parentFile.mkdirs()
infoJson.writeText(infoJsonContent + "\n")
}
companion object {
@OptIn(ExperimentalSerializationApi::class)
private val encoder = Json {
prettyPrint = true
prettyPrintIndent = " "
}
}
}

View file

@ -0,0 +1,95 @@
package dev.adamko.gradle.factorio.tasks
import dev.adamko.gradle.factorio.FactorioModSettings
import javax.inject.Inject
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.gradle.process.ExecOperations
import org.gradle.work.DisableCachingByDefault
import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs
@DisableCachingByDefault(because = "Not a cacheable task")
abstract class LaunchFactorioClientTask @Inject constructor(
private val executor: ExecOperations
) : DefaultTask() {
@get:Input
abstract val currentOs: Property<FactorioModSettings.LocalDev.OS>
@get:Input
@get:Optional
abstract val windowsSteamExe: Property<String>
@get:Input
@get:Optional
abstract val factorioSteamId: Property<String>
@get:Input
@get:Optional
abstract val serverConnectHost: Property<String>
@get:Input
@get:Optional
abstract val clientModsPath: Property<String>
@get:InputFile
@get:Optional
abstract val macFactorioApp: RegularFileProperty
@get:Input
@get:Optional
abstract val launchFactorioCommand: Property<String>
@TaskAction
fun launch() {
val launchCommand =
launchFactorioCommand.orNull ?: when (currentOs.orNull) {
FactorioModSettings.LocalDev.OS.WINDOWS -> windowsCmd()
FactorioModSettings.LocalDev.OS.MAC_OS -> macOSCmd()
null, FactorioModSettings.LocalDev.OS.UNSUPPORTED -> error("no can do, unsupported OS")
}
logger.lifecycle("Launching Factorio client\n > $launchCommand")
executor.exec {
commandLine = parseSpaceSeparatedArgs(launchCommand)
}
}
private fun windowsCmd(): String {
val steamExe = windowsSteamExe.orNull ?: error("missing Steam exe")
val factorioId = factorioSteamId.orNull ?: error("missing Factorio Steam ID")
val modsDirFlag = clientModsPath.map { """--mod-directory "$it"""" }.getOrElse("")
val mpConnectFlag = serverConnectHost.map { "--mp-connect $it" }.getOrElse("")
// commandLine = parseSpaceSeparatedArgs(
//// """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working
//// """explorer "steam://run/$factorioGameId//--mp-connect localhost/" """ // works! But has annoying pop-up
// """ ${steamExe.asFile.orNull?.canonicalPath} -applaunch $factorioGameId --mp-connect localhost --mod-directory ${clientModsDirectory.asFile.orNull?.canonicalPath} """
// )
return """
$steamExe --applaunch $factorioId $modsDirFlag $mpConnectFlag
""".trimIndent()
}
private fun macOSCmd(): String {
// val factorioApp = macFactorioApp.orNull ?: error("missing Factorio app")
val modsDirFlag = "" //clientModsPath.map { """--mod-directory "$it"""" }.getOrElse("")
val mpConnectFlag = serverConnectHost.map { "-mp-connect $it" }.getOrElse("")
return """
/Applications/Steam.app/Contents/MacOS/steam_osx -applaunch 427520 $modsDirFlag $mpConnectFlag
""".trimIndent()
// return """
// open -a "$factorioApp" --args $modsDirFlag $mpConnectFlag
// """.trimIndent()
}
}

View file

@ -0,0 +1,40 @@
package dev.adamko.gradle.factorio.tasks
import javax.inject.Inject
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.tasks.IgnoreEmptyDirectories
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.SkipWhenEmpty
import org.gradle.api.tasks.TaskAction
abstract class LocalPublishFactorioModTask @Inject constructor(
private val files: FileSystemOperations,
) : DefaultTask() {
@get:OutputDirectory
abstract val clientModDirectory: DirectoryProperty
@get:InputFiles
@get:SkipWhenEmpty
@get:PathSensitive(PathSensitivity.NAME_ONLY)
@get:IgnoreEmptyDirectories
abstract val modFiles: ConfigurableFileCollection
@TaskAction
fun install() {
logger.lifecycle("Copying mod from ${modFiles.files} to ${clientModDirectory.asFile.get()}")
files.copy {
from(modFiles) {
include("*.zip")
}
into(clientModDirectory)
}
}
}

View file

@ -0,0 +1,6 @@
package dev.adamko.gradle.factorio.tasks
import org.gradle.api.tasks.bundling.Zip
abstract class PackageFactorioModTask : Zip()

View file

@ -3,7 +3,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
`kotlin-dsl` `kotlin-dsl`
kotlin("jvm") version embeddedKotlinVersion
} }
val gradleJvmTarget = "11" val gradleJvmTarget = "11"
@ -18,15 +17,18 @@ dependencies {
implementation("org.gradle.kotlin:gradle-kotlin-dsl-plugins:$expectedKotlinDslPluginsVersion") implementation("org.gradle.kotlin:gradle-kotlin-dsl-plugins:$expectedKotlinDslPluginsVersion")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${libs.versions.kotlin.get()}")
// https://github.com/gradle/gradle/issues/22510
implementation("org.jetbrains.kotlin:kotlin-sam-with-receiver:${libs.versions.kotlin.get()}")
implementation(platform(libs.kotlin.bom)) implementation(platform(libs.kotlin.bom))
implementation("org.jetbrains.kotlin:kotlin-serialization") implementation("org.jetbrains.kotlin:kotlin-serialization:${libs.versions.kotlin.get()}")
implementation(platform(libs.kotlinx.coroutines.bom)) implementation(platform(libs.kotlinx.coroutines.bom))
} }
kotlin { kotlin {
jvmToolchain { jvmToolchain {
(this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget))
} }
} }

View file

@ -4,7 +4,6 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins { plugins {
id("org.gradle.kotlin.kotlin-dsl") id("org.gradle.kotlin.kotlin-dsl")
kotlin("jvm")
} }
val gradleJvmTarget = 11 val gradleJvmTarget = 11
@ -15,7 +14,7 @@ val gradleJvmTarget = 11
kotlin { kotlin {
jvmToolchain { jvmToolchain {
(this as JavaToolchainSpec).languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget)) languageVersion.set(JavaLanguageVersion.of(gradleJvmTarget))
} }
} }

View file

@ -19,10 +19,10 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
"@fortawesome/fontawesome-free@^6.2.0": "@fortawesome/fontawesome-free@^6.2.1":
version "6.2.0" version "6.2.1"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.2.0.tgz#ba3510825b332816fe7190f28827f8cb33a298b5" resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.2.1.tgz#344baf6ff9eaad7a73cff067d8c56bfc11ae5304"
integrity sha512-CNR7qRIfCwWHNN7FnKUniva94edPdyQzil/zCwk3v6k4R6rR2Fr8i4s3PM7n/lyfPA6Zfko9z5WDzFxG9SW1uQ== integrity sha512-viouXhegu/TjkvYQoiRZK3aax69dGXxgEjpvZW81wIJdxm5Fnvp3VVIP4VHKqX4SvFw6qpmkILkD4RJWAdrt7A==
"@leichtgewicht/ip-codec@^2.0.1": "@leichtgewicht/ip-codec@^2.0.1":
version "2.0.4" version "2.0.4"
@ -126,10 +126,10 @@
"@types/qs" "*" "@types/qs" "*"
"@types/serve-static" "*" "@types/serve-static" "*"
"@types/geojson@7946.0.8": "@types/geojson@7946.0.10":
version "7946.0.8" version "7946.0.10"
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca" resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.10.tgz#6dfbf5ea17142f7f9a043809f1cd4c448cb68249"
integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA== integrity sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==
"@types/glob@5 - 7": "@types/glob@5 - 7":
version "7.2.0" version "7.2.0"
@ -336,22 +336,20 @@
"@webassemblyjs/ast" "1.11.1" "@webassemblyjs/ast" "1.11.1"
"@xtuc/long" "4.2.2" "@xtuc/long" "4.2.2"
"@webpack-cli/configtest@^1.2.0": "@webpack-cli/configtest@^2.0.0":
version "1.2.0" version "2.0.1"
resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.0.1.tgz#a69720f6c9bad6aef54a8fa6ba9c3533e7ef4c7f"
integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== integrity sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==
"@webpack-cli/info@^1.5.0": "@webpack-cli/info@^2.0.0":
version "1.5.0" version "2.0.1"
resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.1.tgz#eed745799c910d20081e06e5177c2b2569f166c0"
integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== integrity sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==
dependencies:
envinfo "^7.7.3"
"@webpack-cli/serve@^1.7.0": "@webpack-cli/serve@^2.0.0":
version "1.7.0" version "2.0.1"
resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.1.tgz#34bdc31727a1889198855913db2f270ace6d7bf8"
integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== integrity sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==
"@xtuc/ieee754@^1.2.0": "@xtuc/ieee754@^1.2.0":
version "1.2.0" version "1.2.0"
@ -530,15 +528,15 @@ bonjour-service@^1.0.11:
fast-deep-equal "^3.1.3" fast-deep-equal "^3.1.3"
multicast-dns "^7.2.5" multicast-dns "^7.2.5"
bootstrap-icons@^1.9.1: bootstrap-icons@^1.10.0:
version "1.9.1" version "1.10.2"
resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.9.1.tgz#cf22d91a25447645e45c49ebde4e56eafdfe761b" resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.10.2.tgz#6a5729e0475e007ed82d752225645e4e6fec48d7"
integrity sha512-d4ZkO30MIkAhQ2nNRJqKXJVEQorALGbLWTuRxyCTJF96lRIV6imcgMehWGJUiJMJhglN0o2tqLIeDnMdiQEE9g== integrity sha512-PTPYadRn1AMGr+QTSxe4ZCc+Wzv9DGZxbi3lNse/dajqV31n2/wl/7NX78ZpkvFgRNmH4ogdIQPQmxAfhEV6nA==
bootstrap@^5.2.2: bootstrap@^5.2.3:
version "5.2.2" version "5.2.3"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.2.tgz#834e053eed584a65e244d8aa112a6959f56e27a0" resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.2.3.tgz#54739f4414de121b9785c5da3c87b37ff008322b"
integrity sha512-dEtzMTV71n6Fhmbg4fYJzQsw1N29hJKO1js5ackCgIpDcGid2ETMGC6zwSYw09v05Y+oRdQ9loC54zB1La3hHQ== integrity sha512-cEKPM+fwb3cT8NzQZYEu4HilJ3anCrWqh3CHAok1p9jXqMPsPTBhU25fBckEJHJ/p+tTxTFTsFQGM+gaHpi3QQ==
brace-expansion@^1.1.7: brace-expansion@^1.1.7:
version "1.1.11" version "1.1.11"
@ -715,10 +713,10 @@ commander@^6.0.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
commander@^7.0.0: commander@^9.4.1:
version "7.2.0" version "9.4.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd"
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==
component-emitter@~1.3.0: component-emitter@~1.3.0:
version "1.3.0" version "1.3.0"
@ -814,19 +812,19 @@ cross-spawn@^7.0.3:
shebang-command "^2.0.0" shebang-command "^2.0.0"
which "^2.0.1" which "^2.0.1"
css-loader@^6.7.1: css-loader@^6.7.2:
version "6.7.1" version "6.7.2"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.2.tgz#26bc22401b5921686a10fbeba75d124228302304"
integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw== integrity sha512-oqGbbVcBJkm8QwmnNzrFrWTnudnRZC+1eXikLJl0n4ljcfotgRifpg2a1lKy8jTrc4/d9A/ap1GFq1jDKG7J+Q==
dependencies: dependencies:
icss-utils "^5.1.0" icss-utils "^5.1.0"
postcss "^8.4.7" postcss "^8.4.18"
postcss-modules-extract-imports "^3.0.0" postcss-modules-extract-imports "^3.0.0"
postcss-modules-local-by-default "^4.0.0" postcss-modules-local-by-default "^4.0.0"
postcss-modules-scope "^3.0.0" postcss-modules-scope "^3.0.0"
postcss-modules-values "^4.0.0" postcss-modules-values "^4.0.0"
postcss-value-parser "^4.2.0" postcss-value-parser "^4.2.0"
semver "^7.3.5" semver "^7.3.8"
css-selector-parser@^1.3: css-selector-parser@^1.3:
version "1.4.1" version "1.4.1"
@ -1554,10 +1552,10 @@ inherits@2.0.3:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==
interpret@^2.2.0: interpret@^3.1.1:
version "2.2.0" version "3.1.1"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4"
integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==
ipaddr.js@1.9.1: ipaddr.js@1.9.1:
version "1.9.1" version "1.9.1"
@ -1576,10 +1574,10 @@ is-binary-path@~2.1.0:
dependencies: dependencies:
binary-extensions "^2.0.0" binary-extensions "^2.0.0"
is-core-module@^2.8.1: is-core-module@^2.9.0:
version "2.9.0" version "2.11.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144"
integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==
dependencies: dependencies:
has "^1.0.3" has "^1.0.3"
@ -1781,15 +1779,15 @@ kind-of@^6.0.2:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
kvision-assets@^6.0.0: kvision-assets@^7.0.4:
version "6.0.0" version "7.0.4"
resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-6.0.0.tgz#de17ec942efd067fc180e7fab4e040c4e41bbe25" resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-7.0.4.tgz#59c62f38b15b44db10699305159be63828a5e645"
integrity sha512-fjPGTMGiboRnXXwhQFVOsRdDaDFnBfAQBRGhbzjQUp5oJKUnPS303Pua0u5atQdYMXyN/u6fyH6TEHgQzM9Wog== integrity sha512-DY2j6Wm3vaMWwBSjnhutOKZQA6pzOvL40hAkUUc52QkrRn4K2E7GHdWR1qGIR4/YyraWvzkVWasr6R4vg8l9mQ==
leaflet@^1.9.2: leaflet@^1.9.3:
version "1.9.2" version "1.9.3"
resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.9.2.tgz#168b6c6ef1d4d1e8409bde2c4ad050c249c4dbe6" resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.9.3.tgz#52ec436954964e2d3d39e0d433da4b2500d74414"
integrity sha512-Kc77HQvWO+y9y2oIs3dn5h5sy2kr3j41ewdqCMEUA4N89lgfUUfOBy7wnnHEstDpefiGFObq12FdopGRMx4J7g== integrity sha512-iB2cR9vAkDOu5l3HAay2obcUHZ7xwUBBjph8+PGtmW/2lYhbLizWtG7nTeYht36WfOslixQF9D/uSIzhZgGMfQ==
loader-runner@^4.2.0: loader-runner@^4.2.0:
version "4.3.0" version "4.3.0"
@ -1984,11 +1982,16 @@ multicast-dns@^7.2.5:
dns-packet "^5.2.2" dns-packet "^5.2.2"
thunky "^1.0.2" thunky "^1.0.2"
nanoid@3.3.3, nanoid@^3.3.1: nanoid@3.3.3:
version "3.3.3" version "3.3.3"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25"
integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==
nanoid@^3.3.4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
navigo@^8.11.1: navigo@^8.11.1:
version "8.11.1" version "8.11.1"
resolved "https://registry.yarnpkg.com/navigo/-/navigo-8.11.1.tgz#aca756dbca40e2da2ae688a2a247ab4f070fcf4a" resolved "https://registry.yarnpkg.com/navigo/-/navigo-8.11.1.tgz#aca756dbca40e2da2ae688a2a247ab4f070fcf4a"
@ -2231,12 +2234,12 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@^8.4.7: postcss@^8.4.18:
version "8.4.12" version "8.4.19"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.12.tgz#1e7de78733b28970fa4743f7da6f3763648b1905" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.19.tgz#61178e2add236b17351897c8bcc0b4c8ecab56fc"
integrity sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg== integrity sha512-h+pbPsyhlYj6N2ozBmHhHrs9DzGmbaarbLvWipMRO7RLS+v4onj26MPFXA5OBYFxyqYhUJK456SwDcY9H2/zsA==
dependencies: dependencies:
nanoid "^3.3.1" nanoid "^3.3.4"
picocolors "^1.0.0" picocolors "^1.0.0"
source-map-js "^1.0.2" source-map-js "^1.0.2"
@ -2321,12 +2324,12 @@ readdirp@~3.6.0:
dependencies: dependencies:
picomatch "^2.2.1" picomatch "^2.2.1"
rechoir@^0.7.0: rechoir@^0.8.0:
version "0.7.1" version "0.8.0"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22"
integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==
dependencies: dependencies:
resolve "^1.9.0" resolve "^1.20.0"
redux-thunk@^2.4.1: redux-thunk@^2.4.1:
version "2.4.1" version "2.4.1"
@ -2372,12 +2375,12 @@ resolve-from@^5.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
resolve@^1.9.0: resolve@^1.20.0:
version "1.22.0" version "1.22.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
dependencies: dependencies:
is-core-module "^2.8.1" is-core-module "^2.9.0"
path-parse "^1.0.7" path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0" supports-preserve-symlinks-flag "^1.0.0"
@ -2444,10 +2447,10 @@ selfsigned@^2.1.1:
dependencies: dependencies:
node-forge "^1" node-forge "^1"
semver@^7.3.5: semver@^7.3.8:
version "7.3.7" version "7.3.8"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
dependencies: dependencies:
lru-cache "^6.0.0" lru-cache "^6.0.0"
@ -2878,22 +2881,23 @@ wbuf@^1.1.0, wbuf@^1.7.3:
dependencies: dependencies:
minimalistic-assert "^1.0.0" minimalistic-assert "^1.0.0"
webpack-cli@4.10.0: webpack-cli@5.0.0:
version "4.10.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.0.0.tgz#bd380a9653e0cd1a08916c4ff1adea17201ef68f"
integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== integrity sha512-AACDTo20yG+xn6HPW5xjbn2Be4KUzQPebWXsDMHwPPyKh9OnTOJgZN2Nc+g/FZKV3ObRTYsGvibAvc+5jAUrVA==
dependencies: dependencies:
"@discoveryjs/json-ext" "^0.5.0" "@discoveryjs/json-ext" "^0.5.0"
"@webpack-cli/configtest" "^1.2.0" "@webpack-cli/configtest" "^2.0.0"
"@webpack-cli/info" "^1.5.0" "@webpack-cli/info" "^2.0.0"
"@webpack-cli/serve" "^1.7.0" "@webpack-cli/serve" "^2.0.0"
colorette "^2.0.14" colorette "^2.0.14"
commander "^7.0.0" commander "^9.4.1"
cross-spawn "^7.0.3" cross-spawn "^7.0.3"
envinfo "^7.7.3"
fastest-levenshtein "^1.0.12" fastest-levenshtein "^1.0.12"
import-local "^3.0.2" import-local "^3.0.2"
interpret "^2.2.0" interpret "^3.1.1"
rechoir "^0.7.0" rechoir "^0.8.0"
webpack-merge "^5.7.3" webpack-merge "^5.7.3"
webpack-dev-middleware@^5.3.1: webpack-dev-middleware@^5.3.1:
@ -2962,10 +2966,10 @@ webpack-sources@^3.2.3:
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
webpack@5.74.0: webpack@5.75.0:
version "5.74.0" version "5.75.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.75.0.tgz#1e440468647b2505860e94c9ff3e44d5b582c152"
integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==
dependencies: dependencies:
"@types/eslint-scope" "^3.7.3" "@types/eslint-scope" "^3.7.3"
"@types/estree" "^0.0.51" "@types/estree" "^0.0.51"

View file

@ -6,13 +6,13 @@
## compilation ## ## compilation ##
jvm = "11" jvm = "11"
kotlin = "1.7.20" kotlin = "1.7.22"
## libs ## ## libs ##
camel-kafkaConnectors = "0.11.0" camel-kafkaConnectors = "0.11.0"
http4k = "4.25.16.2" http4k = "4.25.16.2"
kafka = "3.3.1" # https://kafka.apache.org/downloads kafka = "3.3.1" # https://kafka.apache.org/downloads
kvision = "5.17.0" # https://github.com/rjaros/kvision/releases kvision = "5.18.1" # https://github.com/rjaros/kvision/releases
log4j2 = "2.17.2" log4j2 = "2.17.2"
okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio okio = "3.2.0" # https://search.maven.org/artifact/com.squareup.okio/okio
qosLogback = "1.2.11" qosLogback = "1.2.11"
@ -25,7 +25,7 @@ kxs-charleskornKaml = "0.44.0"
kxs-mamoeYamlkt = "0.12.0" kxs-mamoeYamlkt = "0.12.0"
kxs-kxsTsGen = "0.2.1" kxs-kxsTsGen = "0.2.1"
kotlinJsWrappers = "1.0.0-pre.413" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom kotlinJsWrappers = "1.0.0-pre.456" # https://search.maven.org/artifact/org.jetbrains.kotlin-wrappers/kotlin-wrappers-bom
kotlinx-cli = "0.3.5" # https://github.com/Kotlin/kotlinx-cli/releases kotlinx-cli = "0.3.5" # https://github.com/Kotlin/kotlinx-cli/releases
kotlinx-coroutines = "1.6.4" # https://github.com/Kotlin/kotlinx.coroutines/releases kotlinx-coroutines = "1.6.4" # https://github.com/Kotlin/kotlinx.coroutines/releases
@ -35,9 +35,9 @@ kotlinx-nodejs = "0.0.7"
kSvgDsl = "v2.2.0" kSvgDsl = "v2.2.0"
ktor = "2.1.2" # https://github.com/ktorio/ktor/releases ktor = "2.1.3" # https://github.com/ktorio/ktor/releases
hoplite = "2.6.5" # https://github.com/sksamuel/hoplite/releases hoplite = "2.7.0" # https://github.com/sksamuel/hoplite/releases
simpleSyslogParser = "1.0.0" # https://search.maven.org/artifact/com.github.palindromicity/simple-syslog simpleSyslogParser = "1.0.0" # https://search.maven.org/artifact/com.github.palindromicity/simple-syslog
@ -51,28 +51,28 @@ nimbusJoseJwt = "9.25.6" # https://search.maven.org/artifact/com.
## npm ## ## npm ##
npm-luaTypes = "2.13.0" # https://www.npmjs.com/package/lua-types npm-luaTypes = "2.13.1" # https://www.npmjs.com/package/lua-types
npm-typescriptToLua = "1.10.1" # https://www.npmjs.com/package/typescript-to-lua npm-typescriptToLua = "1.11.1" # https://www.npmjs.com/package/typescript-to-lua
npm-typedFactorio = "1.9.0" # https://github.com/GlassBricks/typed-factorio/blob/main/Changelog.md https://www.npmjs.com/package/typed-factorio npm-typedFactorio = "1.11.0" # https://github.com/GlassBricks/typed-factorio/blob/main/Changelog.md https://www.npmjs.com/package/typed-factorio
npm-typescript = "4.8.4" # https://github.com/microsoft/TypeScript/releases npm-typescript = "4.9" # https://github.com/microsoft/TypeScript/releases
npm-bootswatch = "5.2.2" # https://www.jsdelivr.com/package/npm/bootswatch npm-bootswatch = "5.2.2" # https://www.jsdelivr.com/package/npm/bootswatch
## test ## ## test ##
junit = "5.9.1" # https://github.com/junit-team/junit5/releases junit = "5.9.1" # https://github.com/junit-team/junit5/releases
kotest = "5.5.2" # https://github.com/kotest/kotest/releases kotest = "5.5.4" # https://github.com/kotest/kotest/releases
mockk = "1.13.2" # https://github.com/mockk/mockk/releases/ mockk = "1.13.3" # https://github.com/mockk/mockk/releases/
## infra ## ## infra ##
factorio = "1.1.70" # https://www.factorio.com/download factorio = "1.1.72" # https://www.factorio.com/download
confluent-kafkaConnect = "7.0.1" confluent-kafkaConnect = "7.0.1"
grafana = "8.5.0" grafana = "8.5.0"
prometheus = "v2.34.0" prometheus = "v2.34.0"
## gradle plugins ## ## gradle plugins ##
gradleNodePlugin = "3.4.0" # https://github.com/node-gradle/gradle-node-plugin/releases gradleNodePlugin = "3.5.0" # https://github.com/node-gradle/gradle-node-plugin/releases
######### #########
@ -93,6 +93,7 @@ loggingCapabilities = { id = "dev.jacomet.logging-capabilities", vers
## kotlin ## ## kotlin ##
kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" } kotlin-bom = { group = "org.jetbrains.kotlin", name = "kotlin-bom", version.ref = "kotlin" }
kotlin-embeddableCompiler = { module = "org.jetbrains.kotlin:kotlin-compiler-embeddable" }
kotlinScripting-common = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-common" } kotlinScripting-common = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-common" }
kotlinScripting-jvm = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-jvm" } kotlinScripting-jvm = { group = "org.jetbrains.kotlin", name = "kotlin-scripting-jvm" }

Binary file not shown.

View file

@ -1,5 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

12
gradlew vendored
View file

@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@ -80,10 +80,10 @@ do
esac esac
done done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # This is normally unused
# shellcheck disable=SC2034
APP_NAME="Gradle"
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
@ -143,12 +143,16 @@ fi
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
case $MAX_FD in #( case $MAX_FD in #(
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac

1
gradlew.bat vendored
View file

@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=. if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%

View file

@ -1,4 +1,5 @@
// git update-index --skip-worktree kt52647.gradle.kts
val projectsMustBeConfiguringBuster by tasks.registering { val projectsMustBeConfiguringBuster by tasks.registering {
val buildFile = layout.projectDirectory.file("kt52647.gradle.kts").asFile val buildFile = layout.projectDirectory.file("kt52647.gradle.kts").asFile

View file

@ -7,7 +7,7 @@ import dev.adamko.gradle.factorio.typescriptAttributes
plugins { plugins {
id("kafkatorio.conventions.lang.kotlin-multiplatform") id("kafkatorio.conventions.lang.kotlin-multiplatform")
id("dev.adamko.factorio-mod") apply false // only needed for 'attributes' - need to split up the plugin? id("dev.adamko.factorio-mod-library") // only needed for 'attributes' - need to split up the plugin?
kotlin("plugin.serialization") kotlin("plugin.serialization")
distribution distribution
} }

View file

@ -1,55 +1,27 @@
import dev.adamko.gradle.factorio.mod_portal.FactorioModPublishTask import dev.adamko.gradle.factorio.mod_portal.FactorioModPublishTask
import dev.adamko.gradle.factorio.typescriptAttributes import dev.adamko.gradle.factorio.typescriptAttributes
import dev.adamko.gradle.factorio.factorioModAttributes import kafkatorio.tasks.TypeScriptToLuaTask
import kafkatorio.tasks.TypescriptToLuaTask
import kotlinx.serialization.json.put import kotlinx.serialization.json.put
import kotlinx.serialization.json.putJsonObject import kotlinx.serialization.json.putJsonObject
import net.swiftzer.semver.SemVer
import org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.plugins.ide.idea.model.Module as IdeaImlModule
import org.gradle.plugins.ide.idea.model.Path as IdeaImlPath
plugins { plugins {
id("kafkatorio.conventions.lang.node") id("kafkatorio.conventions.lang.node")
id("dev.adamko.factorio-mod") id("dev.adamko.factorio-mod")
distribution distribution
idea
} }
description = "Sends in-game information to a server over the internet (requires additional setup)" description = "Sends in-game information to a server over the internet (requires additional setup)"
// Factorio required format is: factorioMod {
// - filename: `mod-name_version.zip` modName.set("kafkatorio-events")
// - zip contains one directory, `mod-name` modTitle.set("Kafkatorio Events")
//val modName: String by extra { "${rootProject.name}-events" } modAuthor.set("adam@adamko.dev")
extra.set("modName", "kafkatorio-events") factorioCompatibility.set(libs.versions.factorio.map { it.substringBeforeLast(".") })
val modName = extra.get("modName") as String
val modDescription: String by project.extra { project.description ?: "" }
val distributionZipName: String by extra { "${modName}_${rootProject.version}.zip" }
// version of Factorio that the mod is compatible with (must only be "major.minor" - patch causes error)
val modFactorioCompatibility: Provider<String> =
libs.versions.factorio.map { SemVer.parse(it).run { "$major.$minor" } }
val licenseFile: RegularFile by rootProject.extra
@Suppress("UNCHECKED_CAST")
val projectTokens: MapProperty<String, String> =
rootProject.extra.get("projectTokens") as? MapProperty<String, String>
?: error("error getting projectTokens")
//val projectTokens: MapProperty<String, String> by rootProject.extra
val projectTokensX1 = projectTokens.apply {
put("mod.name", modName)
put("mod.title", "Kafkatorio Events")
put("mod.description", modDescription)
put("factorio.version", modFactorioCompatibility)
} }
val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript") val licenseFile: RegularFile by rootProject.extra
node { node {
nodeProjectDir.set(layout.projectDirectory) nodeProjectDir.set(layout.projectDirectory)
@ -68,7 +40,7 @@ dependencies {
} }
val typescriptToLua by tasks.registering(TypescriptToLuaTask::class) { val typescriptToLua by tasks.registering(TypeScriptToLuaTask::class) {
dependsOn( dependsOn(
tasks.npmInstall, tasks.npmInstall,
installEventsTsSchema, installEventsTsSchema,
@ -77,21 +49,18 @@ val typescriptToLua by tasks.registering(TypescriptToLuaTask::class) {
inputs.file(tasks.updatePackageJson.map { it.packageJsonFile }) inputs.file(tasks.updatePackageJson.map { it.packageJsonFile })
sourceFiles.set(tsSrcDir) sourceFiles.from(factorioMod.mainSources.typescript.sourceDirectories)
outputDirectory.set(layout.projectDirectory.dir("src/generated/lua")) outputDirectory.set(factorioMod.mainSources.typescript.destinationDirectory)
} }
val installEventsTsSchema by tasks.registering(Sync::class) { val installEventsTsSchema by tasks.registering(Sync::class) {
description = "Fetch the latest shared data-model" description = "Fetch the latest shared TypeScript data-model"
group = project.name group = project.name
dependsOn(typescriptEventsSchema) dependsOn(typescriptEventsSchema)
val outputDir = layout.projectDirectory.dir("src/main/typescript/generated/")
outputs.dir(outputDir)
from( from(
provider { typescriptEventsSchema } provider { typescriptEventsSchema }
.map { eventsSchema -> .map { eventsSchema ->
@ -103,78 +72,32 @@ val installEventsTsSchema by tasks.registering(Sync::class) {
.map { zipTree(it) } .map { zipTree(it) }
} }
) { ) {
// drop the first directory inside the zip
// eachFile { relativePath = dropDirectory() }
includeEmptyDirs = false includeEmptyDirs = false
} }
into(outputDir) into(layout.projectDirectory.dir("src/main/typescript/generated"))
} }
val zipNameProvider = provider { distributionZipName }
tasks.distZip { tasks.distZip {
val projectTokensXX22 = projectTokensX1 val distributionZipName = factorioMod.distributionZipName
archiveFileName.set(distributionZipName)
inputs.property("zipNameProvider", zipNameProvider)
inputs.property("projectTokens", projectTokensXX22)
archiveFileName.set(zipNameProvider)
} }
val publishModToPortal by tasks.registering(FactorioModPublishTask::class) { val publishModToPortal by tasks.registering(FactorioModPublishTask::class) {
dependsOn(tasks.check) dependsOn(tasks.check)
distributionZip.set(tasks.distZip.flatMap { it.archiveFile }) distributionZip.set(tasks.distZip.flatMap { it.archiveFile })
val projectModName = project.extra.get("modName") as String modName.set(factorioMod.modName)
modName.set(projectModName) modVersion.set(factorioMod.modVersion)
modVersion.set(project.version.toString())
} }
tasks.assembleFactorioModContents {
distributions { modFiles.apply {
main {
distributionBaseName.set(modName)
val tokens333: MutableMap<String, String> = projectTokensX1.get()
contents {
from(layout.projectDirectory.dir("src/main/resources/mod-data")) {
include("**/**")
}
from(licenseFile)
from(typescriptToLua.map { it.outputDirectory }) from(typescriptToLua.map { it.outputDirectory })
filesNotMatching("**/*.png") { from(licenseFile)
// maybe make a bug report for projectTokensX1 causing null$null$null error?
// val tokens333: MutableMap<String, String> = projectTokensX1.get()
filter<ReplaceTokens>("tokens" to tokens333)
}
includeEmptyDirs = false
exclude {
// exclude empty files
it.file.run {
isFile && useLines { lines -> lines.all { line -> line.isBlank() } }
} }
} }
}
}
}
tasks.withType<Zip>().configureEach {
val projectTokensXX444 = projectTokensX1
inputs.property("projectTokens", projectTokensXX444)
}
val factorioModProvider by configurations.registering {
asProvider()
factorioModAttributes(objects)
outgoing.artifact(tasks.distZip.flatMap { it.archiveFile })
}
val projectPackageJsonName: Provider<String> = val projectPackageJsonName: Provider<String> =
providers.provider { "${rootProject.name}-${project.name}" } providers.provider { "${rootProject.name}-${project.name}" }
@ -201,82 +124,6 @@ tasks.updatePackageJson {
tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) }
val typescriptSrcDir: File = file("src/main/typescript")
val luaSrcDir: File = file("src/generated/lua")
val resourcesDir: File = file("src/main/resources")
val typescriptTestSrcDir: File = file("src/test/typescript")
val generatedSrcDir: File = file("src/generated")
idea {
module {
sourceDirs.plusAssign(
listOf(
typescriptSrcDir,
luaSrcDir,
)
)
// sourceDirs = sourceDirs + file("src/main/lua")
resourceDirs = resourceDirs + resourcesDir
testSourceDirs = testSourceDirs + typescriptTestSrcDir
generatedSourceDirs = generatedSourceDirs + generatedSrcDir
// excludeDirs = excludeDirs + generatedSrcDir
iml {
whenMerged {
require(this is IdeaImlModule)
sourceDirs.plusAssign(
listOf(
typescriptSrcDir,
luaSrcDir,
)
)
generatedSourceFolders.plusAssign(
IdeaImlPath(luaSrcDir.toURI().toString())
)
resourceDirs = resourceDirs + resourcesDir
testSourceDirs = testSourceDirs + typescriptTestSrcDir
// excludeDirs = excludeDirs + generatedSrcDir
}
}
}
}
// trying to get Gradle+idea to recognise the ts-src...
//val typescriptSrcSet = project.objects.sourceDirectorySet("typescript", "TypeScript").apply {
// srcDirs(tsSrcDir)
// compiledBy(typescriptToLua, TypescriptToLuaTask::outputDirectory)
//// destinationDirectory.set(layout.buildDirectory.dir("typescriptToLua"))
//}
//
//val tsSrcConfiguration by configurations.registering {
// asProvider()
// outgoing.artifact(tsSrcDir)
//}
//
//idea {
// module {
// // Not using += due to https://github.com/gradle/gradle/issues/8749
// sourceDirs = sourceDirs + typescriptSrcSet.sourceDirectories
// resourceDirs.add(file("src/main/resources"))
// excludeDirs.add(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile)
// scopes.compute("MAIN") { _: String, scope: MutableMap<String, MutableCollection<Configuration>>? ->
// val s = (scope ?: mutableMapOf())
// s.compute("plus") { _, conf ->
// val c = conf ?: mutableListOf()
// c.add(tsSrcConfiguration.get())
// c
// }
// s
// }
// }
//}
//val downloadFactorioApiDocs by tasks.registering { //val downloadFactorioApiDocs by tasks.registering {
// group = project.name // group = project.name
// //

View file

@ -10,9 +10,9 @@
"integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ==" "integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ=="
}, },
"enhanced-resolve": { "enhanced-resolve": {
"version": "5.10.0", "version": "5.12.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz",
"integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==",
"requires": { "requires": {
"graceful-fs": "^4.2.4", "graceful-fs": "^4.2.4",
"tapable": "^2.2.0" "tapable": "^2.2.0"
@ -37,17 +37,17 @@
} }
}, },
"is-core-module": { "is-core-module": {
"version": "2.10.0", "version": "2.11.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
"integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"requires": { "requires": {
"has": "^1.0.3" "has": "^1.0.3"
} }
}, },
"lua-types": { "lua-types": {
"version": "2.13.0", "version": "2.13.1",
"resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.0.tgz", "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.1.tgz",
"integrity": "sha512-wra+mIPZlcbm8bYoM6QutEwTOAjZ9KyKMiaidGeZ+QJItIAK9hwG+1I6GCDKnW0T9E/Xv2IoTFtZwxQv4zAIJw==" "integrity": "sha512-rRwtvX6kS+5MpuO3xpvKsnYjdSDDI064Qq1OqX8gY+r+0l7m3dFLiZPDFoHqH22jaBpEvcHcPs6+WD7qkdmFsA=="
}, },
"path-parse": { "path-parse": {
"version": "1.0.7", "version": "1.0.7",
@ -80,19 +80,19 @@
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="
}, },
"typed-factorio": { "typed-factorio": {
"version": "1.9.0", "version": "1.11.0",
"resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.9.0.tgz", "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-1.11.0.tgz",
"integrity": "sha512-k3qVo5ehUYgJItQp4BT4MtAodzeUgLk3Wzf3TG53SNdce1vYfIdmlNMjfG17wkOpoCBCA1p6XvMQxkWcbk23ZA==" "integrity": "sha512-RYCEpcECiQ2dw1tj03bPv6fRXCevuAP89ipMBv67FsY09+W7ApZkfjXIJq9RaxoIMtbGkqPUql33O/DYVMtAng=="
}, },
"typescript": { "typescript": {
"version": "4.8.4", "version": "4.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz",
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==" "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA=="
}, },
"typescript-to-lua": { "typescript-to-lua": {
"version": "1.10.1", "version": "1.11.1",
"resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.10.1.tgz", "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.11.1.tgz",
"integrity": "sha512-R6KQc1YzFcejyaZ9tAvVK0MFTlRS1b10vON5sxjtGVSUWl+W4KRLik0LDCgKfI0wnDQH+LNVnKBNUsBfTtEoQQ==", "integrity": "sha512-XxGOf0zBRrMocGr4BbVaJdnvnk4yTrUs0BCdamfb/Qg94hKZg8ydRUy17ZtHZfYmnwFupR88R5DZXIpHYP0S5g==",
"requires": { "requires": {
"@typescript-to-lua/language-extensions": "1.0.0", "@typescript-to-lua/language-extensions": "1.0.0",
"enhanced-resolve": "^5.8.2", "enhanced-resolve": "^5.8.2",

View file

@ -11,10 +11,10 @@
}, },
"devDependencies": {}, "devDependencies": {},
"dependencies": { "dependencies": {
"lua-types": "2.13.0", "lua-types": "2.13.1",
"typescript-to-lua": "1.10.1", "typescript-to-lua": "1.11.1",
"typed-factorio": "1.9.0", "typed-factorio": "1.11.0",
"typescript": "4.8.4" "typescript": "4.9"
}, },
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"peerDependencies": {}, "peerDependencies": {},

View file

@ -1,15 +0,0 @@
local ____exports = {}
local ____global_2Dinit = require("main.global-init")
local initGlobal = ____global_2Dinit.initGlobal
local ____prototypeUpdates = require("main.events.prototypeUpdates")
local emitPrototypes = ____prototypeUpdates.emitPrototypes
require("main.events.registerEventListeners")
require("main.events.mapChunkUpdates")
require("main.events.playerUpdates")
require("main.events.entityUpdates")
require("main.commands.kafkatorioCommands")
script.on_init(function()
initGlobal(true)
emitPrototypes()
end)
return ____exports

View file

@ -1,82 +0,0 @@
local ____exports = {}
____exports.KafkatorioPacketData = {}
local KafkatorioPacketData = ____exports.KafkatorioPacketData
do
KafkatorioPacketData.Type = Type or ({})
KafkatorioPacketData.Type.ConfigurationUpdate = "kafkatorio.packet.instant.ConfigurationUpdate"
KafkatorioPacketData.Type.ConsoleChatUpdate = "kafkatorio.packet.instant.ConsoleChatUpdate"
KafkatorioPacketData.Type.ConsoleCommandUpdate = "kafkatorio.packet.instant.ConsoleCommandUpdate"
KafkatorioPacketData.Type.PrototypesUpdate = "kafkatorio.packet.instant.PrototypesUpdate"
KafkatorioPacketData.Type.SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate"
KafkatorioPacketData.Type.EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate"
KafkatorioPacketData.Type.MapChunkEntityUpdate = "kafkatorio.packet.keyed.MapChunkEntityUpdate"
KafkatorioPacketData.Type.MapChunkResourceUpdate = "kafkatorio.packet.keyed.MapChunkResourceUpdate"
KafkatorioPacketData.Type.MapChunkTileUpdate = "kafkatorio.packet.keyed.MapChunkTileUpdate"
KafkatorioPacketData.Type.PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate"
KafkatorioPacketData.Type.Error = "kafkatorio.packet.KafkatorioPacketData.Error"
end
____exports.FactorioPrototype = {}
local FactorioPrototype = ____exports.FactorioPrototype
do
FactorioPrototype.Type = Type or ({})
FactorioPrototype.Type.Entity = "kafkatorio.prototype.Entity"
FactorioPrototype.Type.MapTile = "kafkatorio.prototype.MapTile"
end
____exports.ChunkSize = ChunkSize or ({})
____exports.ChunkSize.CHUNK_512 = "CHUNK_512"
____exports.ChunkSize.CHUNK_256 = "CHUNK_256"
____exports.ChunkSize.CHUNK_128 = "CHUNK_128"
____exports.ChunkSize.CHUNK_064 = "CHUNK_064"
____exports.ChunkSize.CHUNK_032 = "CHUNK_032"
____exports.MinedProduct = {}
local MinedProduct = ____exports.MinedProduct
do
MinedProduct.Type = Type or ({})
MinedProduct.Type.MinedProductFluid = "kafkatorio.resource.MinedProduct.MinedProductFluid"
MinedProduct.Type.MinedProductItem = "kafkatorio.resource.MinedProduct.MinedProductItem"
end
____exports.FactorioEntityStatus = FactorioEntityStatus or ({})
____exports.FactorioEntityStatus.WORKING = "WORKING"
____exports.FactorioEntityStatus.NORMAL = "NORMAL"
____exports.FactorioEntityStatus.NO_POWER = "NO_POWER"
____exports.FactorioEntityStatus.LOW_POWER = "LOW_POWER"
____exports.FactorioEntityStatus.NO_FUEL = "NO_FUEL"
____exports.FactorioEntityStatus.DISABLED_BY_CONTROL_BEHAVIOR = "DISABLED_BY_CONTROL_BEHAVIOR"
____exports.FactorioEntityStatus.OPENED_BY_CIRCUIT_NETWORK = "OPENED_BY_CIRCUIT_NETWORK"
____exports.FactorioEntityStatus.CLOSED_BY_CIRCUIT_NETWORK = "CLOSED_BY_CIRCUIT_NETWORK"
____exports.FactorioEntityStatus.DISABLED_BY_SCRIPT = "DISABLED_BY_SCRIPT"
____exports.FactorioEntityStatus.MARKED_FOR_DECONSTRUCTION = "MARKED_FOR_DECONSTRUCTION"
____exports.FactorioEntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK = "NOT_PLUGGED_IN_ELECTRIC_NETWORK"
____exports.FactorioEntityStatus.NETWORKS_CONNECTED = "NETWORKS_CONNECTED"
____exports.FactorioEntityStatus.NETWORKS_DISCONNECTED = "NETWORKS_DISCONNECTED"
____exports.FactorioEntityStatus.CHARGING = "CHARGING"
____exports.FactorioEntityStatus.DISCHARGING = "DISCHARGING"
____exports.FactorioEntityStatus.FULLY_CHARGED = "FULLY_CHARGED"
____exports.FactorioEntityStatus.OUT_OF_LOGISTIC_NETWORK = "OUT_OF_LOGISTIC_NETWORK"
____exports.FactorioEntityStatus.NO_RECIPE = "NO_RECIPE"
____exports.FactorioEntityStatus.NO_INGREDIENTS = "NO_INGREDIENTS"
____exports.FactorioEntityStatus.NO_INPUT_FLUID = "NO_INPUT_FLUID"
____exports.FactorioEntityStatus.NO_RESEARCH_IN_PROGRESS = "NO_RESEARCH_IN_PROGRESS"
____exports.FactorioEntityStatus.NO_MINABLE_RESOURCES = "NO_MINABLE_RESOURCES"
____exports.FactorioEntityStatus.LOW_INPUT_FLUID = "LOW_INPUT_FLUID"
____exports.FactorioEntityStatus.FLUID_INGREDIENT_SHORTAGE = "FLUID_INGREDIENT_SHORTAGE"
____exports.FactorioEntityStatus.FULL_OUTPUT = "FULL_OUTPUT"
____exports.FactorioEntityStatus.ITEM_INGREDIENT_SHORTAGE = "ITEM_INGREDIENT_SHORTAGE"
____exports.FactorioEntityStatus.MISSING_REQUIRED_FLUID = "MISSING_REQUIRED_FLUID"
____exports.FactorioEntityStatus.MISSING_SCIENCE_PACKS = "MISSING_SCIENCE_PACKS"
____exports.FactorioEntityStatus.WAITING_FOR_SOURCE_ITEMS = "WAITING_FOR_SOURCE_ITEMS"
____exports.FactorioEntityStatus.WAITING_FOR_SPACE_IN_DESTINATION = "WAITING_FOR_SPACE_IN_DESTINATION"
____exports.FactorioEntityStatus.PREPARING_ROCKET_FOR_LAUNCH = "PREPARING_ROCKET_FOR_LAUNCH"
____exports.FactorioEntityStatus.WAITING_TO_LAUNCH_ROCKET = "WAITING_TO_LAUNCH_ROCKET"
____exports.FactorioEntityStatus.LAUNCHING_ROCKET = "LAUNCHING_ROCKET"
____exports.FactorioEntityStatus.NO_MODULES_TO_TRANSMIT = "NO_MODULES_TO_TRANSMIT"
____exports.FactorioEntityStatus.RECHARGING_AFTER_POWER_OUTAGE = "RECHARGING_AFTER_POWER_OUTAGE"
____exports.FactorioEntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT = "WAITING_FOR_TARGET_TO_BE_BUILT"
____exports.FactorioEntityStatus.WAITING_FOR_TRAIN = "WAITING_FOR_TRAIN"
____exports.FactorioEntityStatus.NO_AMMO = "NO_AMMO"
____exports.FactorioEntityStatus.LOW_TEMPERATURE = "LOW_TEMPERATURE"
____exports.FactorioEntityStatus.DISABLED = "DISABLED"
____exports.FactorioEntityStatus.TURNED_OFF_DURING_DAYTIME = "TURNED_OFF_DURING_DAYTIME"
____exports.FactorioEntityStatus.NOT_CONNECTED_TO_RAIL = "NOT_CONNECTED_TO_RAIL"
____exports.FactorioEntityStatus.CANT_DIVIDE_SEGMENTS = "CANT_DIVIDE_SEGMENTS"
return ____exports

File diff suppressed because it is too large Load diff

View file

@ -1,76 +0,0 @@
local ____lualib = require("lualib_bundle")
local __TS__StringStartsWith = ____lualib.__TS__StringStartsWith
local __TS__StringSplit = ____lualib.__TS__StringSplit
local __TS__ParseInt = ____lualib.__TS__ParseInt
local ____exports = {}
local ____global_2Dinit = require("main.global-init")
local initGlobal = ____global_2Dinit.initGlobal
local ____prototypeUpdates = require("main.events.prototypeUpdates")
local emitPrototypes = ____prototypeUpdates.emitPrototypes
local ____EventDataQueue = require("main.emitting.EventDataQueue")
local EventDataQueue = ____EventDataQueue.default
commands.add_command(
"kafkatorio",
"kafkatorio innit bruv",
function(e)
local ____temp_0
if e.player_index ~= nil then
____temp_0 = game.get_player(e.player_index)
else
____temp_0 = nil
end
local player = ____temp_0
if e.parameter == nil then
if player ~= nil then
player.print("no parameter")
end
else
local paramUppercase = string.upper(e.parameter)
if "PROTOTYPES" == paramUppercase then
emitPrototypes()
elseif __TS__StringStartsWith(paramUppercase, "CHUNKS") then
local ____paramUppercase_split_result__1_1 = __TS__StringSplit(paramUppercase, " ")
if ____paramUppercase_split_result__1_1 ~= nil then
____paramUppercase_split_result__1_1 = ____paramUppercase_split_result__1_1[2]
end
local size = ____paramUppercase_split_result__1_1 or nil
local radius = size ~= nil and __TS__ParseInt(size) or 1
if e.player_index ~= nil then
local player = game.players[e.player_index]
local chunkPosition = {
x = math.floor(player.position.x / 32),
y = math.floor(player.position.y / 32)
}
local chunkXMin = chunkPosition.x - radius
local chunkXMax = chunkPosition.x + radius
local chunkYMin = chunkPosition.y - radius
local chunkYMax = chunkPosition.y + radius
local chunkCount = 0
for ____, surface in pairs(game.surfaces) do
for chunk in surface.get_chunks() do
if chunk.x >= chunkXMin and chunk.x <= chunkXMax and (chunk.y >= chunkYMin and chunk.y <= chunkYMax) then
local data = {
name = defines.events.on_chunk_generated,
position = {x = chunk.x, y = chunk.y},
area = chunk.area,
surface = surface,
tick = e.tick
}
EventDataQueue:enqueue(
(tostring(surface.index) .. tostring(chunk.x)) .. tostring(chunk.y),
data,
50
)
chunkCount = chunkCount + 1
end
end
end
player.print(((((((((("enqueued " .. tostring(chunkCount)) .. " chunks from [x:") .. tostring(chunkXMin)) .. ", y:") .. tostring(chunkYMin)) .. "] to [x:") .. tostring(chunkXMax)) .. ", y:") .. tostring(chunkYMax)) .. "]")
end
elseif __TS__StringStartsWith(paramUppercase, "INIT_GLOBAL") then
initGlobal(__TS__StringStartsWith(paramUppercase, "INIT_GLOBAL FORCE"))
end
end
end
)
return ____exports

View file

@ -1,141 +0,0 @@
local ____lualib = require("lualib_bundle")
local __TS__Class = ____lualib.__TS__Class
local __TS__New = ____lualib.__TS__New
local ____exports = {}
local CacheEntry
local ____KafkatorioSettings = require("main.settings.KafkatorioSettings")
local KafkatorioSettings = ____KafkatorioSettings.default
local ____PacketEmitter = require("main.emitting.PacketEmitter")
local PacketEmitter = ____PacketEmitter.default
____exports.EventUpdatesManager = __TS__Class()
local EventUpdatesManager = ____exports.EventUpdatesManager
EventUpdatesManager.name = "EventUpdatesManager"
function EventUpdatesManager.prototype.____constructor(self)
self:init()
end
function EventUpdatesManager.prototype.init(self, force)
local isAnythingUndefined = global.eventUpdatesManagerCache == nil
log(((("Initialising EventDataCache (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")...")
if force == true or isAnythingUndefined then
log("Initialising global.cache")
global.eventUpdatesManagerCache = {}
end
log("Finished initialising EventDataCache")
end
function EventUpdatesManager.prototype.throttle(self, key, ____type, mutate, expirationDurationTicks)
self:update(
key,
____type,
mutate,
false,
expirationDurationTicks
)
end
function EventUpdatesManager.prototype.debounce(self, key, ____type, mutate, expirationDurationTicks)
self:update(
key,
____type,
mutate,
true,
expirationDurationTicks
)
end
function EventUpdatesManager.prototype.update(self, key, ____type, mutate, resetLastUpdated, expirationDurationTicks)
local entry = self:getCacheEntry(key, ____type) or ____exports.EventUpdatesManager:createCacheEntry(key, ____type)
mutate(entry.packet)
if resetLastUpdated then
entry.lastUpdatedTick = game.tick
end
if expirationDurationTicks ~= nil then
entry.expirationDurationTicks = expirationDurationTicks
end
if entry.expirationDurationTicks ~= nil and entry.expirationDurationTicks <= 0 then
self:extractAndEmitExpiredPackets()
end
end
function EventUpdatesManager.prototype.setExpiration(self, key, ____type, expirationDurationTicks)
local entry = self:getCacheEntry(key, ____type)
if entry ~= nil then
entry.expirationDurationTicks = expirationDurationTicks
end
end
function EventUpdatesManager.prototype.extractExpired(self)
local countExpired = 0
local countTotal = 0
local expiredData = {}
for key, entry in pairs(global.eventUpdatesManagerCache) do
countTotal = countTotal + 1
if self:isExpired(entry) then
countExpired = countExpired + 1
expiredData[#expiredData + 1] = entry.packet
global.eventUpdatesManagerCache[key] = nil
end
end
local hasExpiredItems = countExpired > 0
local hasAnyItem = countTotal > 0
if hasExpiredItems or game.tick % 30 == 0 and hasAnyItem then
log((("[extractExpired] expired items: " .. tostring(countExpired)) .. ", total: ") .. tostring(countTotal))
end
return expiredData
end
function EventUpdatesManager.prototype.extractAndEmitExpiredPackets(self)
local cachedEvents = self:extractExpired()
if #cachedEvents > 0 then
log((("[EventDataCache] emitting " .. tostring(#cachedEvents)) .. " events on tick ") .. tostring(game.tick))
for ____, event in ipairs(cachedEvents) do
PacketEmitter:emitKeyedPacket(event)
end
end
return #cachedEvents
end
function EventUpdatesManager.prototype.getCacheEntry(self, key, ____type)
local hash = ____exports.EventUpdatesManager:hashKey(key)
if not (global.eventUpdatesManagerCache[hash] ~= nil) then
return nil
end
local value = global.eventUpdatesManagerCache[hash]
if self:isEntryInstanceOf(value, ____type) then
return value
else
return nil
end
end
function EventUpdatesManager.createCacheEntry(self, key, ____type)
local data = {type = ____type, key = key}
local entry = __TS__New(CacheEntry, data)
local hash = ____exports.EventUpdatesManager:hashKey(key)
global.eventUpdatesManagerCache[hash] = entry
return entry
end
function EventUpdatesManager.prototype.isExpired(self, entry)
local expiryDuration = entry.expirationDurationTicks or KafkatorioSettings:getEventCacheExpirationTicks(entry.packet)
if expiryDuration == nil then
return true
else
return game.tick - entry.lastUpdatedTick > expiryDuration
end
end
function EventUpdatesManager.prototype.isEntryInstanceOf(self, entry, ____type)
local ____self_isDataInstanceOf_2 = self.isDataInstanceOf
local ____entry_packet_0 = entry
if ____entry_packet_0 ~= nil then
____entry_packet_0 = ____entry_packet_0.packet
end
return ____self_isDataInstanceOf_2(self, ____entry_packet_0, ____type)
end
function EventUpdatesManager.prototype.isDataInstanceOf(self, packet, ____type)
return packet ~= nil and packet.type == ____type
end
function EventUpdatesManager.hashKey(self, key)
return game.encode_string(game.table_to_json(key))
end
local EventUpdates = __TS__New(____exports.EventUpdatesManager)
____exports.default = EventUpdates
CacheEntry = __TS__Class()
CacheEntry.name = "CacheEntry"
function CacheEntry.prototype.____constructor(self, packet, expirationDurationTicks)
self.lastUpdatedTick = game.tick
self.packet = packet
self.expirationDurationTicks = expirationDurationTicks
end
return ____exports

View file

@ -1,87 +0,0 @@
local ____lualib = require("lualib_bundle")
local __TS__Class = ____lualib.__TS__Class
local __TS__New = ____lualib.__TS__New
local ____exports = {}
local Node
____exports.EventDataQueueManager = __TS__Class()
local EventDataQueueManager = ____exports.EventDataQueueManager
EventDataQueueManager.name = "EventDataQueueManager"
function EventDataQueueManager.prototype.____constructor(self)
end
function EventDataQueueManager.init(self, force)
local isAnythingUndefined = global.store == nil or global.size == nil or global.head == nil or global.tail == nil
log(((("Initialising EventDataQueueManager globals (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")")
if force == true or isAnythingUndefined then
global.store = {}
global.head = nil
global.tail = nil
global.size = 0
end
log("Finished initialising EventDataQueueManager")
end
function EventDataQueueManager.prototype.size(self)
return global.size
end
function EventDataQueueManager.prototype.enqueue(self, key, event, weight)
if weight == nil then
weight = 1
end
if global.store[key] ~= nil then
local node = __TS__New(Node, key, weight)
if global.head == nil then
global.head = node
end
if global.tail ~= nil then
global.tail.next = node
end
global.tail = node
global.size = global.size + 1
end
global.store[key] = event
end
function EventDataQueueManager.prototype.dequeue(self)
if global.head == nil then
return nil
else
local weight = global.head.weight
local storeKey = global.head.storeKey
global.head = global.head.next
global.size = global.size - 1
local storedPacket = global.store[storeKey]
global.store[storeKey] = nil
if storedPacket == nil then
return nil
else
return {value = storedPacket, weight = weight}
end
end
end
function EventDataQueueManager.prototype.dequeueValues(self, targetWeight)
if targetWeight == nil then
targetWeight = 50
end
local values = {}
local weight = 0
repeat
do
local packet = self:dequeue()
if packet == nil then
break
else
weight = weight + packet.weight
values[#values + 1] = packet.value
end
end
until not (weight <= targetWeight)
return values
end
local EventDataQueue = __TS__New(____exports.EventDataQueueManager)
____exports.default = EventDataQueue
Node = __TS__Class()
Node.name = "Node"
function Node.prototype.____constructor(self, storeKey, weight)
self.next = nil
self.storeKey = storeKey
self.weight = weight
end
return ____exports

View file

@ -1,48 +0,0 @@
local ____lualib = require("lualib_bundle")
local __TS__Class = ____lualib.__TS__Class
local __TS__SetDescriptor = ____lualib.__TS__SetDescriptor
local __TS__New = ____lualib.__TS__New
local ____exports = {}
--- Simple ordered queue for {@link KafkatorioPacketData}.
--
-- Implemented so printing multiple packets won't flood the output log, causing messages to be
-- missed or garbled.
____exports.KafkatorioPacketQueueManager = __TS__Class()
local KafkatorioPacketQueueManager = ____exports.KafkatorioPacketQueueManager
KafkatorioPacketQueueManager.name = "KafkatorioPacketQueueManager"
function KafkatorioPacketQueueManager.prototype.____constructor(self)
self.size = 0
self.first = nil
self.last = nil
end
__TS__SetDescriptor(
KafkatorioPacketQueueManager.prototype,
"length",
{get = function(self)
return self.size
end},
true
)
function KafkatorioPacketQueueManager.prototype.enqueue(self, packet)
local last = self.last
self.last = {value = packet}
if last ~= nil then
last.next = self.last
end
if self.first == nil then
self.first = self.last
end
self.size = self.size + 1
end
function KafkatorioPacketQueueManager.prototype.dequeue(self)
local first = self.first
if first == nil then
return nil
end
self.first = first.next or nil
self.size = self.size - 1
return first.value
end
local KafkatorioPacketQueue = __TS__New(____exports.KafkatorioPacketQueueManager)
____exports.default = KafkatorioPacketQueue
return ____exports

View file

@ -1,33 +0,0 @@
local ____lualib = require("lualib_bundle")
local __TS__Class = ____lualib.__TS__Class
local __TS__StringTrim = ____lualib.__TS__StringTrim
local __TS__New = ____lualib.__TS__New
local ____exports = {}
____exports.KafkatorioPacketEmitter = __TS__Class()
local KafkatorioPacketEmitter = ____exports.KafkatorioPacketEmitter
KafkatorioPacketEmitter.name = "KafkatorioPacketEmitter"
function KafkatorioPacketEmitter.prototype.____constructor(self)
end
function KafkatorioPacketEmitter.prototype.emitInstantPacket(self, data)
____exports.KafkatorioPacketEmitter:emitPacket({data = data, modVersion = global.MOD_VERSION, tick = game.tick})
end
function KafkatorioPacketEmitter.prototype.emitKeyedPacket(self, data)
____exports.KafkatorioPacketEmitter:emitPacket({data = data, modVersion = global.MOD_VERSION, tick = game.tick})
end
function KafkatorioPacketEmitter.emitPacket(self, packet)
local data = game.table_to_json(packet)
if #__TS__StringTrim(data) <= 0 then
print("[error] table_to_json returned empty string for packet:" .. tostring(packet))
return
end
local encodedData = game.encode_string(data)
if encodedData == nil or #__TS__StringTrim(encodedData) <= 0 then
print("[error] could not encode packet")
print("KafkatorioPacket:::" .. data)
else
print("KafkatorioPacket:::encoded:" .. encodedData)
end
end
local PacketEmitter = __TS__New(____exports.KafkatorioPacketEmitter)
____exports.default = PacketEmitter
return ____exports

View file

@ -1,13 +0,0 @@
local ____exports = {}
local ____global_2Dinit = require("main.global-init")
local initGlobal = ____global_2Dinit.initGlobal
local ____prototypeUpdates = require("main.events.prototypeUpdates")
local emitPrototypes = ____prototypeUpdates.emitPrototypes
local ____ConfigurationUpdateHandler = require("main.events.handlers.ConfigurationUpdateHandler")
local ConfigurationUpdates = ____ConfigurationUpdateHandler.default
script.on_configuration_changed(function(data)
initGlobal(true)
ConfigurationUpdates:emitConfigurationUpdate(data)
emitPrototypes()
end)
return ____exports

View file

@ -1,20 +0,0 @@
local ____exports = {}
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue")
local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default
script.on_event(
defines.events.on_console_chat,
function(event)
local update = {type = KafkatorioPacketData.Type.ConsoleChatUpdate, authorPlayerIndex = event.player_index or nil, content = event.message}
KafkatorioPacketQueue:enqueue(update)
end
)
script.on_event(
defines.events.on_console_command,
function(event)
local update = {type = KafkatorioPacketData.Type.ConsoleCommandUpdate, authorPlayerIndex = event.player_index or nil, command = event.command, parameters = event.parameters}
KafkatorioPacketQueue:enqueue(update)
end
)
return ____exports

View file

@ -1,162 +0,0 @@
local ____exports = {}
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
local ChunkSize = ____kafkatorio_2Dschema.ChunkSize
local FactorioEntityStatus = ____kafkatorio_2Dschema.FactorioEntityStatus
local MinedProduct = ____kafkatorio_2Dschema.MinedProduct
____exports.Converters = {}
local Converters = ____exports.Converters
do
local EntityStatusRecord
function Converters.prototypeId(____type, name)
return (____type .. "/") .. name
end
local floor = math.floor
local mapEventIdToName = {}
for eventName, eventId in pairs(defines.events) do
mapEventIdToName[eventId] = eventName
end
function Converters.eventNameString(event)
return mapEventIdToName[event]
end
function Converters.mapColour(color)
return {color.r or 0, color.g or 0, color.b or 0, color.a or 0}
end
function Converters.convertPlacedTiles(placedTile, oldTiles)
local converted = {}
for ____, tile in ipairs(oldTiles) do
converted[#converted + 1] = {position = {x = tile.position.x, y = tile.position.y}, name = placedTile.name}
end
return converted
end
function Converters.convertRemovedTiles(surface, oldTiles)
local converted = {}
for ____, tile in ipairs(oldTiles) do
converted[#converted + 1] = surface.get_tile(tile.position.x, tile.position.y)
end
return converted
end
function Converters.convertCollisionMaskToNames(cm)
local masks = {}
for name in pairs(cm) do
masks[#masks + 1] = name
end
return masks
end
local function convertEntityStatus(status)
if status == nil then
return nil
else
return EntityStatusRecord[status]
end
end
function Converters.prototypeIdEntity(entity)
return Converters.prototypeId(entity.type, entity.name)
end
function Converters.tilePositionToChunkPosition(mapPosition)
return {
floor(mapPosition.x / 32),
floor(mapPosition.y / 32),
ChunkSize.CHUNK_032
}
end
function Converters.mapPositionToChunkPosition(mapPosition)
return {
floor(mapPosition.x / 32),
floor(mapPosition.y / 32),
ChunkSize.CHUNK_032
}
end
function Converters.entityPosition(position)
return {position.x, position.y}
end
function Converters.chunkPosition(position)
return {position.x, position.y, ChunkSize.CHUNK_032}
end
function Converters.entityStatus(status)
if status == nil then
return nil
else
return EntityStatusRecord[status]
end
end
function Converters.miningProperties(properties)
local products = {}
if properties.products ~= nil then
for ____, product in ipairs(properties.products) do
if product.type == "fluid" then
products[#products + 1] = {
type = MinedProduct.Type.MinedProductFluid,
amount = product.amount,
resultProtoId = ____exports.Converters.prototypeId(product.type, product.name)
}
end
if product.type == "item" then
products[#products + 1] = {
type = MinedProduct.Type.MinedProductItem,
amount = product.amount,
resultProtoId = ____exports.Converters.prototypeId(product.type, product.name)
}
end
end
end
return {canBeMined = properties.minable, products = products}
end
function Converters.playerOnlineInfo(player, data)
data.lastOnline = player.last_online
data.onlineTime = player.online_time
data.afkTime = player.afk_time
data.isConnected = player.connected
end
function Converters.collisionBox(collision_box)
return {
leftTop = ____exports.Converters.entityPosition(collision_box.left_top),
rightBottom = ____exports.Converters.entityPosition(collision_box.right_bottom)
}
end
EntityStatusRecord = {
[defines.entity_status.cant_divide_segments] = FactorioEntityStatus.CANT_DIVIDE_SEGMENTS,
[defines.entity_status.charging] = FactorioEntityStatus.CHARGING,
[defines.entity_status.closed_by_circuit_network] = FactorioEntityStatus.CLOSED_BY_CIRCUIT_NETWORK,
[defines.entity_status.disabled] = FactorioEntityStatus.DISABLED,
[defines.entity_status.disabled_by_control_behavior] = FactorioEntityStatus.DISABLED_BY_CONTROL_BEHAVIOR,
[defines.entity_status.disabled_by_script] = FactorioEntityStatus.DISABLED_BY_SCRIPT,
[defines.entity_status.discharging] = FactorioEntityStatus.DISCHARGING,
[defines.entity_status.fluid_ingredient_shortage] = FactorioEntityStatus.FLUID_INGREDIENT_SHORTAGE,
[defines.entity_status.fully_charged] = FactorioEntityStatus.FULLY_CHARGED,
[defines.entity_status.full_output] = FactorioEntityStatus.FULL_OUTPUT,
[defines.entity_status.item_ingredient_shortage] = FactorioEntityStatus.ITEM_INGREDIENT_SHORTAGE,
[defines.entity_status.launching_rocket] = FactorioEntityStatus.LAUNCHING_ROCKET,
[defines.entity_status.low_input_fluid] = FactorioEntityStatus.LOW_INPUT_FLUID,
[defines.entity_status.low_power] = FactorioEntityStatus.LOW_POWER,
[defines.entity_status.low_temperature] = FactorioEntityStatus.LOW_TEMPERATURE,
[defines.entity_status.marked_for_deconstruction] = FactorioEntityStatus.MARKED_FOR_DECONSTRUCTION,
[defines.entity_status.missing_required_fluid] = FactorioEntityStatus.MISSING_REQUIRED_FLUID,
[defines.entity_status.missing_science_packs] = FactorioEntityStatus.MISSING_SCIENCE_PACKS,
[defines.entity_status.networks_connected] = FactorioEntityStatus.NETWORKS_CONNECTED,
[defines.entity_status.networks_disconnected] = FactorioEntityStatus.NETWORKS_DISCONNECTED,
[defines.entity_status.normal] = FactorioEntityStatus.NORMAL,
[defines.entity_status.not_connected_to_rail] = FactorioEntityStatus.NOT_CONNECTED_TO_RAIL,
[defines.entity_status.not_plugged_in_electric_network] = FactorioEntityStatus.NOT_PLUGGED_IN_ELECTRIC_NETWORK,
[defines.entity_status.no_ammo] = FactorioEntityStatus.NO_AMMO,
[defines.entity_status.no_fuel] = FactorioEntityStatus.NO_FUEL,
[defines.entity_status.no_ingredients] = FactorioEntityStatus.NO_INGREDIENTS,
[defines.entity_status.no_input_fluid] = FactorioEntityStatus.NO_INPUT_FLUID,
[defines.entity_status.no_minable_resources] = FactorioEntityStatus.NO_MINABLE_RESOURCES,
[defines.entity_status.no_modules_to_transmit] = FactorioEntityStatus.NO_MODULES_TO_TRANSMIT,
[defines.entity_status.no_power] = FactorioEntityStatus.NO_POWER,
[defines.entity_status.no_recipe] = FactorioEntityStatus.NO_RECIPE,
[defines.entity_status.no_research_in_progress] = FactorioEntityStatus.NO_RESEARCH_IN_PROGRESS,
[defines.entity_status.opened_by_circuit_network] = FactorioEntityStatus.OPENED_BY_CIRCUIT_NETWORK,
[defines.entity_status.out_of_logistic_network] = FactorioEntityStatus.OUT_OF_LOGISTIC_NETWORK,
[defines.entity_status.preparing_rocket_for_launch] = FactorioEntityStatus.PREPARING_ROCKET_FOR_LAUNCH,
[defines.entity_status.recharging_after_power_outage] = FactorioEntityStatus.RECHARGING_AFTER_POWER_OUTAGE,
[defines.entity_status.turned_off_during_daytime] = FactorioEntityStatus.TURNED_OFF_DURING_DAYTIME,
[defines.entity_status.waiting_for_source_items] = FactorioEntityStatus.WAITING_FOR_SOURCE_ITEMS,
[defines.entity_status.waiting_for_space_in_destination] = FactorioEntityStatus.WAITING_FOR_SPACE_IN_DESTINATION,
[defines.entity_status.waiting_for_target_to_be_built] = FactorioEntityStatus.WAITING_FOR_TARGET_TO_BE_BUILT,
[defines.entity_status.waiting_for_train] = FactorioEntityStatus.WAITING_FOR_TRAIN,
[defines.entity_status.waiting_to_launch_rocket] = FactorioEntityStatus.WAITING_TO_LAUNCH_ROCKET,
[defines.entity_status.working] = FactorioEntityStatus.WORKING
}
end
return ____exports

View file

@ -1,32 +0,0 @@
local ____exports = {}
local ____EntityUpdateHandler = require("main.events.handlers.EntityUpdateHandler")
local EntityUpdates = ____EntityUpdateHandler.default
script.on_event(
defines.events.on_built_entity,
function(e)
log("on_built_entity " .. tostring(e.tick))
EntityUpdates:handleBuiltEntityEvent(e)
end
)
script.on_event(
defines.events.on_robot_built_entity,
function(e)
log("on_robot_built_entity " .. tostring(e.tick))
EntityUpdates:handleBuiltEntityEvent(e)
end
)
script.on_event(
defines.events.on_player_mined_entity,
function(e)
log("on_player_mined_entity " .. tostring(e.tick))
EntityUpdates:handleMinedEntityEvent(e)
end
)
script.on_event(
defines.events.on_robot_mined_entity,
function(e)
log("on_robot_mined_entity " .. tostring(e.tick))
EntityUpdates:handleMinedEntityEvent(e)
end
)
return ____exports

View file

@ -1,6 +0,0 @@
local ____exports = {}
function ____exports.isEventType(eventData, ____type)
local id = eventData.name
return id == ____type
end
return ____exports

View file

@ -1,62 +0,0 @@
local ____lualib = require("lualib_bundle")
local __TS__Class = ____lualib.__TS__Class
local __TS__ObjectKeys = ____lualib.__TS__ObjectKeys
local __TS__ArrayConcat = ____lualib.__TS__ArrayConcat
local Set = ____lualib.Set
local __TS__New = ____lualib.__TS__New
local __TS__Spread = ____lualib.__TS__Spread
local __TS__ArrayMap = ____lualib.__TS__ArrayMap
local ____exports = {}
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue")
local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default
____exports.ConfigurationUpdateHandler = __TS__Class()
local ConfigurationUpdateHandler = ____exports.ConfigurationUpdateHandler
ConfigurationUpdateHandler.name = "ConfigurationUpdateHandler"
function ConfigurationUpdateHandler.prototype.____constructor(self)
end
function ConfigurationUpdateHandler.prototype.emitConfigurationUpdate(self, changeData)
local configUpdateData = {
type = KafkatorioPacketData.Type.ConfigurationUpdate,
migrationApplied = changeData.migration_applied,
modStartupSettingsChange = changeData.mod_startup_settings_changed,
allMods = ____exports.ConfigurationUpdateHandler:allMods(changeData),
factorioData = ____exports.ConfigurationUpdateHandler:factorioData(changeData)
}
KafkatorioPacketQueue:enqueue(configUpdateData)
end
function ConfigurationUpdateHandler.factorioData(self, changeData)
return {oldVersion = changeData.old_version or nil, newVersion = changeData.new_version or nil}
end
function ConfigurationUpdateHandler.allMods(self, e)
local namesOfChangedMods = __TS__ObjectKeys(e.mod_changes)
local namesOfCurrentMods = __TS__ObjectKeys(script.active_mods)
local modNames = {__TS__Spread(__TS__New(
Set,
__TS__ArrayConcat(namesOfChangedMods, namesOfCurrentMods)
))}
return __TS__ArrayMap(
modNames,
function(____, modName)
local ____script_active_mods_modName_2 = script.active_mods[modName]
if ____script_active_mods_modName_2 == nil then
local ____e_mod_changes_modName_new_version_0 = e.mod_changes[modName]
if ____e_mod_changes_modName_new_version_0 ~= nil then
____e_mod_changes_modName_new_version_0 = ____e_mod_changes_modName_new_version_0.new_version
end
____script_active_mods_modName_2 = ____e_mod_changes_modName_new_version_0
end
local currentVer = ____script_active_mods_modName_2 or nil
local ____e_mod_changes_modName_old_version_3 = e.mod_changes[modName]
if ____e_mod_changes_modName_old_version_3 ~= nil then
____e_mod_changes_modName_old_version_3 = ____e_mod_changes_modName_old_version_3.old_version
end
local previousVer = ____e_mod_changes_modName_old_version_3 or nil
return {modName = modName, currentVersion = currentVer, previousVersion = previousVer}
end
)
end
local ConfigurationUpdates = __TS__New(____exports.ConfigurationUpdateHandler)
____exports.default = ConfigurationUpdates
return ____exports

View file

@ -1,176 +0,0 @@
local ____lualib = require("lualib_bundle")
local __TS__Class = ____lualib.__TS__Class
local __TS__New = ____lualib.__TS__New
local ____exports = {}
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
local ____converters = require("main.events.converters")
local Converters = ____converters.Converters
local ____EventDataCache = require("main.emitting.EventDataCache")
local EventDataCache = ____EventDataCache.default
____exports.EntityUpdatesHandler = __TS__Class()
local EntityUpdatesHandler = ____exports.EntityUpdatesHandler
EntityUpdatesHandler.name = "EntityUpdatesHandler"
function EntityUpdatesHandler.prototype.____constructor(self)
end
function EntityUpdatesHandler.prototype.handleMinedTileEvent(self, event)
local surface = game.get_surface(event.surface_index)
if surface == nil then
return
end
local tilesByChunk = {}
for ____, tile in ipairs(event.tiles) do
local chunkPosition = Converters.tilePositionToChunkPosition(tile.position)
if not (tilesByChunk[chunkPosition] ~= nil) then
tilesByChunk[chunkPosition] = {}
end
local tiles = tilesByChunk[chunkPosition]
tiles[#tiles + 1] = tile
tilesByChunk[chunkPosition] = tiles
end
for chunkPos, tiles in pairs(tilesByChunk) do
local entities = {}
for ____, tile in ipairs(tiles) do
local tileEntities = ____exports.EntityUpdatesHandler:getTileResourceEntities(surface, tile.position)
for ____, resource in ipairs(tileEntities) do
entities[#entities + 1] = resource
end
end
____exports.EntityUpdatesHandler:throttleResourcesUpdate(
Converters.eventNameString(event.name),
event.tick,
event.surface_index,
chunkPos,
entities
)
end
end
function EntityUpdatesHandler.prototype.handleMinedEntityEvent(self, event)
____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.entity)
end
function EntityUpdatesHandler.prototype.handleBuiltEntityEvent(self, event)
____exports.EntityUpdatesHandler:throttleEntityUpdate(event, event.created_entity)
end
function EntityUpdatesHandler.prototype.handleChunkGeneratedEvent(self, event)
local entities = ____exports.EntityUpdatesHandler:getAreaResourceEntities(event.surface, event.area)
____exports.EntityUpdatesHandler:throttleResourcesUpdate(
Converters.eventNameString(event.name),
event.tick,
event.surface.index,
Converters.chunkPosition(event.position),
entities
)
end
function EntityUpdatesHandler.throttleEntityUpdate(self, event, entity)
if entity.unit_number == nil then
return
end
local eventName = Converters.eventNameString(event.name)
local entityUpdateKey = {
protoId = Converters.prototypeIdEntity(entity),
surfaceIndex = entity.surface.index,
chunkPosition = Converters.mapPositionToChunkPosition(entity.position)
}
local ____entity_unit_number_2 = entity.unit_number
local ____entity_graphics_variation_3 = entity.graphics_variation
local ____entity_health_4 = entity.health
local ____entity_active_5 = entity.active
local ____entity_rotatable_6 = entity.rotatable
local ____entity_last_user_index_0 = entity.last_user
if ____entity_last_user_index_0 ~= nil then
____entity_last_user_index_0 = ____entity_last_user_index_0.index
end
local entityUpdate = {
unitNumber = ____entity_unit_number_2,
graphicsVariation = ____entity_graphics_variation_3,
health = ____entity_health_4,
isActive = ____entity_active_5,
isRotatable = ____entity_rotatable_6,
lastUser = ____entity_last_user_index_0,
status = Converters.entityStatus(entity.status)
}
EventDataCache:throttle(
entityUpdateKey,
KafkatorioPacketData.Type.MapChunkEntityUpdate,
function(data)
if data.events == nil then
data.events = {}
end
local ____data_events_7, ____eventName_8 = data.events, eventName
if ____data_events_7[____eventName_8] == nil then
____data_events_7[____eventName_8] = {}
end
local ____data_events_eventName_9 = data.events[eventName]
____data_events_eventName_9[#____data_events_eventName_9 + 1] = event.tick
if data.entitiesXY == nil then
data.entitiesXY = {}
end
local ____data_entitiesXY_10, ____tostring_result_11 = data.entitiesXY, tostring(entity.position.x)
if ____data_entitiesXY_10[____tostring_result_11] == nil then
____data_entitiesXY_10[____tostring_result_11] = {}
end
local ____data_entitiesXY_tostring_result_12, ____tostring_result_13 = data.entitiesXY[tostring(entity.position.x)], tostring(entity.position.y)
if ____data_entitiesXY_tostring_result_12[____tostring_result_13] == nil then
____data_entitiesXY_tostring_result_12[____tostring_result_13] = entityUpdate
end
end
)
end
function EntityUpdatesHandler.throttleResourcesUpdate(self, eventName, eventTick, surfaceIndex, chunkPosition, entities)
local entitiesByProtoId = {}
for ____, entity in ipairs(entities) do
local protoId = Converters.prototypeIdEntity(entity)
if entitiesByProtoId[protoId] == nil then
entitiesByProtoId[protoId] = {}
end
local ____entitiesByProtoId_protoId_14 = entitiesByProtoId[protoId]
____entitiesByProtoId_protoId_14[#____entitiesByProtoId_protoId_14 + 1] = entity
end
for protoId, resourceEntities in pairs(entitiesByProtoId) do
local entityUpdateKey = {protoId = protoId, surfaceIndex = surfaceIndex, chunkPosition = chunkPosition}
EventDataCache:throttle(
entityUpdateKey,
KafkatorioPacketData.Type.MapChunkResourceUpdate,
function(data)
if data.events == nil then
data.events = {}
end
local ____data_events_15, ____eventName_16 = data.events, eventName
if ____data_events_15[____eventName_16] == nil then
____data_events_15[____eventName_16] = {}
end
local ____data_events_eventName_17 = data.events[eventName]
____data_events_eventName_17[#____data_events_eventName_17 + 1] = eventTick
for ____, entity in ipairs(resourceEntities) do
if data.amounts == nil then
data.amounts = {}
end
local ____data_amounts_18, ____tostring_result_19 = data.amounts, tostring(entity.position.x)
if ____data_amounts_18[____tostring_result_19] == nil then
____data_amounts_18[____tostring_result_19] = {}
end
data.amounts[tostring(entity.position.x)][tostring(entity.position.y)] = entity.amount
if entity.initial_amount ~= nil then
if data.initialAmounts == nil then
data.initialAmounts = {}
end
local ____data_initialAmounts_20, ____tostring_result_21 = data.initialAmounts, tostring(entity.position.x)
if ____data_initialAmounts_20[____tostring_result_21] == nil then
____data_initialAmounts_20[____tostring_result_21] = {}
end
data.initialAmounts[tostring(entity.position.x)][tostring(entity.position.y)] = entity.initial_amount
end
end
end
)
end
end
function EntityUpdatesHandler.getTileResourceEntities(self, surface, mapPosition)
return surface.find_entities_filtered({position = mapPosition, collision_mask = "resource-layer"})
end
function EntityUpdatesHandler.getAreaResourceEntities(self, surface, area)
return surface.find_entities_filtered({area = area, collision_mask = "resource-layer"})
end
local EntityUpdates = __TS__New(____exports.EntityUpdatesHandler)
____exports.default = EntityUpdates
return ____exports

View file

@ -1,208 +0,0 @@
local ____lualib = require("lualib_bundle")
local __TS__Class = ____lualib.__TS__Class
local Map = ____lualib.Map
local __TS__Iterator = ____lualib.__TS__Iterator
local __TS__New = ____lualib.__TS__New
local ____exports = {}
local ____converters = require("main.events.converters")
local Converters = ____converters.Converters
local ____eventTypeCheck = require("main.events.eventTypeCheck")
local isEventType = ____eventTypeCheck.isEventType
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
local ____EventDataCache = require("main.emitting.EventDataCache")
local EventUpdates = ____EventDataCache.default
local MapChunkUpdateHandler = __TS__Class()
MapChunkUpdateHandler.name = "MapChunkUpdateHandler"
function MapChunkUpdateHandler.prototype.____constructor(self)
end
function MapChunkUpdateHandler.prototype.handleChunkGeneratedEvent(self, event, expirationDurationTicks)
local tiles = event.surface.find_tiles_filtered({area = event.area})
MapChunkUpdateHandler:mapTilesUpdateDebounce(
event.surface,
Converters.chunkPosition(event.position),
tiles,
event,
nil,
expirationDurationTicks
)
end
function MapChunkUpdateHandler.prototype.handleBuiltTileEvent(self, event)
local surface = game.get_surface(event.surface_index)
if surface == nil then
local eventName = Converters.eventNameString(event.name)
log("[handleBuiltTileEvent] undefined surface " .. eventName)
return
end
local tiles = Converters.convertPlacedTiles(event.tile, event.tiles)
local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles)
for ____, ____value in __TS__Iterator(groupedTiles) do
local chunkPos = ____value[1]
local tiles = ____value[2]
MapChunkUpdateHandler:mapTilesUpdateDebounce(
surface,
chunkPos,
tiles,
event,
function(data)
if isEventType(event, defines.events.on_player_built_tile) then
data.player = event.player_index
return
end
if isEventType(event, defines.events.on_robot_built_tile) then
local ____data_2 = data
local ____event_robot_unit_number_0 = event.robot
if ____event_robot_unit_number_0 ~= nil then
____event_robot_unit_number_0 = ____event_robot_unit_number_0.unit_number
end
____data_2.robot = {
unitNumber = ____event_robot_unit_number_0 or nil,
protoId = Converters.prototypeId(event.robot.type, event.robot.name)
}
return
end
local exhaustiveCheck = event
end
)
end
end
function MapChunkUpdateHandler.prototype.handleMinedTileEvent(self, event)
local surface = game.get_surface(event.surface_index)
if surface == nil then
local eventName = Converters.eventNameString(event.name)
log("[handleMinedTileEvent] undefined surface " .. eventName)
return
end
local tiles = Converters.convertRemovedTiles(surface, event.tiles)
local groupedTiles = MapChunkUpdateHandler:groupTiles(tiles)
for ____, ____value in __TS__Iterator(groupedTiles) do
local chunkPos = ____value[1]
local tiles = ____value[2]
MapChunkUpdateHandler:mapTilesUpdateDebounce(
surface,
chunkPos,
tiles,
event,
function(data)
if isEventType(event, defines.events.on_player_mined_tile) then
data.player = event.player_index
return
end
if isEventType(event, defines.events.on_robot_mined_tile) then
local ____data_5 = data
local ____event_robot_unit_number_3 = event.robot
if ____event_robot_unit_number_3 ~= nil then
____event_robot_unit_number_3 = ____event_robot_unit_number_3.unit_number
end
____data_5.robot = {
unitNumber = ____event_robot_unit_number_3 or nil,
protoId = Converters.prototypeId(event.robot.type, event.robot.name)
}
return
end
local exhaustiveCheck = event
end
)
end
end
function MapChunkUpdateHandler.prototype.handleScriptSetTilesEvent(self, event)
local surface = game.get_surface(event.surface_index)
if surface == nil then
return
end
local groupedTiles = MapChunkUpdateHandler:groupTiles(event.tiles)
for ____, ____value in __TS__Iterator(groupedTiles) do
local chunkPos = ____value[1]
local tiles = ____value[2]
MapChunkUpdateHandler:mapTilesUpdateDebounce(surface, chunkPos, tiles, event)
end
end
function MapChunkUpdateHandler.prototype.handlePreChunkDeleted(self, event)
local surface = game.get_surface(event.surface_index)
if surface == nil then
return
end
for ____, position in ipairs(event.positions) do
local key = {
surfaceIndex = surface.index,
chunkPosition = Converters.chunkPosition(position)
}
EventUpdates:debounce(
key,
KafkatorioPacketData.Type.MapChunkTileUpdate,
function(data)
data.isDeleted = true
return true
end,
0
)
end
end
function MapChunkUpdateHandler.mapTilesUpdateDebounce(self, surface, chunkPosition, tiles, event, updater, expirationDurationTicks)
if surface == nil then
return
end
local eventName = Converters.eventNameString(event.name)
local key = {surfaceIndex = surface.index, chunkPosition = chunkPosition}
EventUpdates:debounce(
key,
KafkatorioPacketData.Type.MapChunkTileUpdate,
function(data)
if data.tileDictionary == nil then
data.tileDictionary = {tilesXY = {}, protos = {}}
end
local protosCount = table_size(data.tileDictionary.protos)
for ____, tile in ipairs(tiles) do
local protoId = Converters.prototypeId("tile", tile.name)
if data.tileDictionary.protos[protoId] == nil then
end
local ____data_tileDictionary_protos_7, ____protoId_8 = data.tileDictionary.protos, protoId
if ____data_tileDictionary_protos_7[____protoId_8] == nil then
local ____protosCount_6 = protosCount
protosCount = ____protosCount_6 + 1
____data_tileDictionary_protos_7[____protoId_8] = ____protosCount_6
end
local protoKey = data.tileDictionary.protos[protoId]
local xString = tostring(tile.position.x)
local yString = tostring(tile.position.y)
local ____data_tileDictionary_tilesXY_9, ____xString_10 = data.tileDictionary.tilesXY, xString
if ____data_tileDictionary_tilesXY_9[____xString_10] == nil then
____data_tileDictionary_tilesXY_9[____xString_10] = {}
end
data.tileDictionary.tilesXY[xString][yString] = protoKey
end
if data.events == nil then
data.events = {}
end
local ____data_events_11, ____eventName_12 = data.events, eventName
if ____data_events_11[____eventName_12] == nil then
____data_events_11[____eventName_12] = {}
end
local ____data_events_eventName_13 = data.events[eventName]
____data_events_eventName_13[#____data_events_eventName_13 + 1] = event.tick
if updater ~= nil then
updater(data)
end
end,
expirationDurationTicks
)
end
function MapChunkUpdateHandler.groupTiles(self, tiles)
local mapChunkPositionToTiles = __TS__New(Map)
for ____, tile in ipairs(tiles) do
local chunkPosition = Converters.tilePositionToChunkPosition(tile.position)
if not mapChunkPositionToTiles:has(chunkPosition) then
mapChunkPositionToTiles:set(chunkPosition, {})
end
local ____mapChunkPositionToTiles_get_result_push_result_14 = mapChunkPositionToTiles:get(chunkPosition)
if ____mapChunkPositionToTiles_get_result_push_result_14 ~= nil then
local ____temp_15 = mapChunkPositionToTiles:get(chunkPosition)
____temp_15[#____temp_15 + 1] = tile
____mapChunkPositionToTiles_get_result_push_result_14 = nil
end
end
return mapChunkPositionToTiles
end
local MapChunkUpdate = __TS__New(MapChunkUpdateHandler)
____exports.default = MapChunkUpdate
return ____exports

View file

@ -1,60 +0,0 @@
local ____lualib = require("lualib_bundle")
local __TS__Class = ____lualib.__TS__Class
local __TS__New = ____lualib.__TS__New
local ____exports = {}
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
local ____converters = require("main.events.converters")
local Converters = ____converters.Converters
local ____EventDataCache = require("main.emitting.EventDataCache")
local EventUpdates = ____EventDataCache.default
____exports.PlayerUpdateHandler = __TS__Class()
local PlayerUpdateHandler = ____exports.PlayerUpdateHandler
PlayerUpdateHandler.name = "PlayerUpdateHandler"
function PlayerUpdateHandler.prototype.____constructor(self)
end
function PlayerUpdateHandler.prototype.handleBannedEvent(self, event)
self:playerUpdateThrottle(
event,
function(player, data)
data.bannedReason = event.reason or nil
Converters.playerOnlineInfo(player, data)
end
)
end
function PlayerUpdateHandler.prototype.playerUpdateThrottle(self, event, mutate, expirationDurationTicks)
if expirationDurationTicks == nil then
expirationDurationTicks = nil
end
local playerIndex = event.player_index
if playerIndex == nil then
return
end
local eventName = Converters.eventNameString(event.name)
EventUpdates:throttle(
{index = playerIndex},
KafkatorioPacketData.Type.PlayerUpdate,
function(data)
local player = game.players[playerIndex]
if player ~= nil then
mutate(player, data)
end
if data.events == nil then
data.events = {}
end
local ____data_events_0, ____eventName_1 = data.events, eventName
if ____data_events_0[____eventName_1] == nil then
____data_events_0[____eventName_1] = {}
end
local ____data_events_eventName_2 = data.events[eventName]
____data_events_eventName_2[#____data_events_eventName_2 + 1] = event.tick
end,
expirationDurationTicks
)
end
function PlayerUpdateHandler.prototype.playerUpdateImmediate(self, event, mutate)
self:playerUpdateThrottle(event, mutate, 0)
end
local PlayerUpdates = __TS__New(____exports.PlayerUpdateHandler)
____exports.default = PlayerUpdates
return ____exports

View file

@ -1,57 +0,0 @@
local ____exports = {}
local ____EntityUpdateHandler = require("main.events.handlers.EntityUpdateHandler")
local EntityUpdates = ____EntityUpdateHandler.default
local ____MapChunkUpdateHandler = require("main.events.handlers.MapChunkUpdateHandler")
local MapChunkUpdate = ____MapChunkUpdateHandler.default
script.on_event(
defines.events.on_chunk_generated,
function(e)
log("on_chunk_generated " .. tostring(e.tick))
MapChunkUpdate:handleChunkGeneratedEvent(e)
EntityUpdates:handleChunkGeneratedEvent(e)
end
)
script.on_event(
defines.events.script_raised_set_tiles,
function(event)
log("script_raised_set_tiles " .. tostring(event.tick))
MapChunkUpdate:handleScriptSetTilesEvent(event)
end
)
script.on_event(
defines.events.on_player_built_tile,
function(e)
log("on_player_built_tile " .. tostring(e.tick))
MapChunkUpdate:handleBuiltTileEvent(e)
end
)
script.on_event(
defines.events.on_robot_built_tile,
function(e)
log("on_robot_built_tile " .. tostring(e.tick))
MapChunkUpdate:handleBuiltTileEvent(e)
end
)
script.on_event(
defines.events.on_player_mined_tile,
function(e)
log("on_player_mined_tile " .. tostring(e.tick))
MapChunkUpdate:handleMinedTileEvent(e)
EntityUpdates:handleMinedTileEvent(e)
end
)
script.on_event(
defines.events.on_robot_mined_tile,
function(e)
log("on_robot_mined_tile " .. tostring(e.tick))
MapChunkUpdate:handleMinedTileEvent(e)
end
)
script.on_event(
defines.events.on_pre_chunk_deleted,
function(e)
log("on_pre_chunk_deleted " .. tostring(e.tick))
MapChunkUpdate:handlePreChunkDeleted(e)
end
)
return ____exports

View file

@ -1,129 +0,0 @@
local ____exports = {}
local disconnectReasons
local ____converters = require("main.events.converters")
local Converters = ____converters.Converters
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
local ____PacketEmitter = require("main.emitting.PacketEmitter")
local packetEmitter = ____PacketEmitter.default
local ____PlayerUpdateHandler = require("main.events.handlers.PlayerUpdateHandler")
local PlayerUpdates = ____PlayerUpdateHandler.default
script.on_event(
defines.events.on_player_joined_game,
function(e)
PlayerUpdates:playerUpdateThrottle(
e,
function(player, data)
data.isAdmin = player.admin
local ____data_2 = data
local ____player_character_unit_number_0 = player.character
if ____player_character_unit_number_0 ~= nil then
____player_character_unit_number_0 = ____player_character_unit_number_0.unit_number
end
____data_2.characterUnitNumber = ____player_character_unit_number_0 or nil
data.chatColour = Converters.mapColour(player.chat_color)
data.colour = Converters.mapColour(player.color)
data.forceIndex = player.force.index
data.name = player.name
data.isShowOnMap = player.show_on_map
data.isSpectator = player.spectator
data.surfaceIndex = player.surface.index
data.tag = player.tag
Converters.playerOnlineInfo(player, data)
end
)
end
)
script.on_event(
defines.events.on_player_changed_position,
function(e)
PlayerUpdates:playerUpdateThrottle(
e,
function(player, data)
data.position = {player.position.x, player.position.y}
end
)
end
)
script.on_event(
defines.events.on_player_changed_surface,
function(e)
PlayerUpdates:playerUpdateThrottle(
e,
function(player, data)
data.position = {player.position.x, player.position.y}
data.surfaceIndex = player.surface.index
end
)
end
)
script.on_event(
defines.events.on_player_died,
function(e)
PlayerUpdates:playerUpdateThrottle(
e,
function(player, data)
data.ticksToRespawn = player.ticks_to_respawn or nil
Converters.playerOnlineInfo(player, data)
if e.cause ~= nil then
data.diedCause = {
unitNumber = e.cause.unit_number or nil,
protoId = Converters.prototypeId(e.cause.type, e.cause.name)
}
end
end
)
end
)
script.on_event(
defines.events.on_player_banned,
function(event)
PlayerUpdates:handleBannedEvent(event)
end
)
script.on_event(
defines.events.on_player_unbanned,
function(event)
PlayerUpdates:handleBannedEvent(event)
end
)
script.on_event(
defines.events.on_player_kicked,
function(event)
log((("on_player_kicked " .. tostring(event.tick)) .. " ") .. tostring(event.name))
PlayerUpdates:playerUpdateImmediate(
event,
function(player, data)
data.kickedReason = event.reason or nil
Converters.playerOnlineInfo(player, data)
end
)
end
)
script.on_event(
defines.events.on_pre_player_left_game,
function(event)
log((("on_pre_player_left_game " .. tostring(event.tick)) .. " ") .. tostring(event.name))
local playerUpdateKey = {index = event.player_index}
local playerUpdate = {type = KafkatorioPacketData.Type.PlayerUpdate, key = playerUpdateKey, disconnectReason = disconnectReasons[event.reason]}
packetEmitter:emitKeyedPacket(playerUpdate)
end
)
script.on_event(
defines.events.on_player_removed,
function(event)
log((("on_player_removed " .. tostring(event.tick)) .. " ") .. tostring(event.name))
PlayerUpdates:playerUpdateImmediate(
event,
function(player, data)
data.isRemoved = true
Converters.playerOnlineInfo(player, data)
end
)
end
)
disconnectReasons = {}
for name, disconnectId in pairs(defines.disconnect_reason) do
disconnectReasons[disconnectId] = name
end
return ____exports

View file

@ -1,83 +0,0 @@
local ____exports = {}
local emit, getMapTilePrototypes, getEntityPrototypes, convertItemGroup, convertItemSubgroup
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
local FactorioPrototype = ____kafkatorio_2Dschema.FactorioPrototype
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
local ____converters = require("main.events.converters")
local Converters = ____converters.Converters
local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue")
local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default
function emit(protosByType)
for ____, protos in pairs(protosByType) do
KafkatorioPacketQueue:enqueue({type = KafkatorioPacketData.Type.PrototypesUpdate, prototypes = protos})
end
end
function getMapTilePrototypes()
local tiles = {}
for ____, tile in pairs(game.tile_prototypes) do
tiles[#tiles + 1] = {
type = FactorioPrototype.Type.MapTile,
protoId = Converters.prototypeId("tile", tile.name),
order = tile.order,
layer = tile.layer,
collisionMasks = Converters.convertCollisionMaskToNames(tile.collision_mask),
mapColour = Converters.mapColour(tile.map_color),
canBeMined = tile.mineable_properties.minable
}
end
return {tiles = tiles}
end
function getEntityPrototypes()
local protos = {}
for ____, entity in pairs(game.entity_prototypes) do
local key = (((tostring(entity.group.name) .. "/") .. tostring(entity.subgroup.name)) .. "/") .. entity.type
if protos[key] == nil then
protos[key] = {}
end
local entityProto = {
type = FactorioPrototype.Type.Entity,
protoId = Converters.prototypeId(entity.type, entity.name),
group = convertItemGroup(entity.group),
subgroup = convertItemSubgroup(entity.subgroup),
isBuilding = entity.is_building,
isEntityWithOwner = entity.is_entity_with_owner,
isMilitaryTarget = entity.is_military_target,
maxHealth = entity.max_health,
collisionBox = Converters.collisionBox(entity.collision_box),
tileWidth = entity.tile_width,
tileHeight = entity.tile_height
}
if entity.map_color ~= nil then
entityProto.mapColour = Converters.mapColour(entity.map_color)
end
if entity.friendly_map_color ~= nil then
entityProto.mapColourFriend = Converters.mapColour(entity.friendly_map_color)
end
if entity.enemy_map_color ~= nil then
entityProto.mapColourEnemy = Converters.mapColour(entity.enemy_map_color)
end
entityProto.miningProperties = Converters.miningProperties(entity.mineable_properties)
local ____protos_key_0 = protos[key]
____protos_key_0[#____protos_key_0 + 1] = entityProto
end
return protos
end
function convertItemGroup(itemGroup)
return {name = itemGroup.name, type = itemGroup.type, parentName = nil}
end
function convertItemSubgroup(itemGroup)
local ____itemGroup_name_3 = itemGroup.name
local ____itemGroup_type_4 = itemGroup.type
local ____itemGroup_group_name_1 = itemGroup.group
if ____itemGroup_group_name_1 ~= nil then
____itemGroup_group_name_1 = ____itemGroup_group_name_1.name
end
return {name = ____itemGroup_name_3, type = ____itemGroup_type_4, parentName = ____itemGroup_group_name_1 or nil}
end
function ____exports.emitPrototypes()
local mapTileProtos = getMapTilePrototypes()
emit(mapTileProtos)
local entityProtos = getEntityPrototypes()
emit(entityProtos)
end
return ____exports

View file

@ -1,57 +0,0 @@
local ____exports = {}
local ____eventTypeCheck = require("main.events.eventTypeCheck")
local isEventType = ____eventTypeCheck.isEventType
local ____converters = require("main.events.converters")
local Converters = ____converters.Converters
local ____surfaceUpdates = require("main.events.surfaceUpdates")
local handleSurfaceUpdate = ____surfaceUpdates.handleSurfaceUpdate
local ____EventDataCache = require("main.emitting.EventDataCache")
local EventCacheService = ____EventDataCache.default
local ____MapChunkUpdateHandler = require("main.events.handlers.MapChunkUpdateHandler")
local MapChunkUpdate = ____MapChunkUpdateHandler.default
local ____KafkatorioPacketQueue = require("main.emitting.KafkatorioPacketQueue")
local KafkatorioPacketQueue = ____KafkatorioPacketQueue.default
local ____PacketEmitter = require("main.emitting.PacketEmitter")
local PacketEmitter = ____PacketEmitter.default
local ____EventDataQueue = require("main.emitting.EventDataQueue")
local EventDataQueue = ____EventDataQueue.default
script.on_event(
defines.events.on_tick,
function(event)
if event.tick % 1000 == 0 then
for ____, surface in pairs(game.surfaces) do
handleSurfaceUpdate(
event,
Converters.eventNameString(event.name),
surface
)
end
end
local kPacket = KafkatorioPacketQueue:dequeue()
if kPacket ~= nil then
PacketEmitter:emitInstantPacket(kPacket)
end
if event.tick % 6 == 0 then
local emittedCount = EventCacheService:extractAndEmitExpiredPackets()
if emittedCount > 0 then
log(((("[on_tick:" .. tostring(event.tick)) .. "] emitted ") .. tostring(emittedCount)) .. " events")
end
end
if event.tick % 7 == 0 then
local events = EventDataQueue:dequeueValues(1)
if #events > 0 then
log((((("[on_tick:" .. tostring(event.tick)) .. "] dequeued ") .. tostring(#events)) .. " events, current size: ") .. tostring(EventDataQueue:size()))
local i = 1
for ____, event in ipairs(events) do
if isEventType(event, defines.events.on_chunk_generated) then
local eName = Converters.eventNameString(event.name)
log((((("[on_tick:" .. tostring(event.tick)) .. "] dequed event ") .. eName) .. ", delay ") .. tostring(i))
MapChunkUpdate:handleChunkGeneratedEvent(event, i)
i = i + 1
end
end
end
end
end
)
return ____exports

View file

@ -1,6 +0,0 @@
script.on_event(
defines.events.on_runtime_mod_setting_changed,
function(e)
print((((((("Settings changed " .. e.setting_type) .. ", ") .. tostring(e.player_index)) .. ", ") .. e.setting) .. ", ") .. tostring(e.mod_name))
end
)

View file

@ -1,11 +0,0 @@
local ____exports = {}
local ____PacketEmitter = require("main.emitting.PacketEmitter")
local PacketEmitter = ____PacketEmitter.default
local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema")
local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData
local Type = KafkatorioPacketData.Type
function ____exports.handleSurfaceUpdate(event, eventType, surface)
local update = {type = Type.SurfaceUpdate, name = surface.name, index = surface.index, daytime = surface.daytime}
PacketEmitter:emitInstantPacket(update)
end
return ____exports

View file

@ -1,17 +0,0 @@
local ____exports = {}
local ____EventDataCache = require("main.emitting.EventDataCache")
local EventUpdates = ____EventDataCache.default
local ____EventDataQueue = require("main.emitting.EventDataQueue")
local EventDataQueueManager = ____EventDataQueue.EventDataQueueManager
function ____exports.initGlobal(force)
if force == nil then
force = false
end
log(("Initialising Kafkatorio Global variables (force=" .. tostring(force)) .. ")...")
global.MOD_VERSION = script.active_mods[script.mod_name]
global.FACTORIO_VERSION = script.active_mods.base
EventDataQueueManager:init(true)
EventUpdates:init(true)
log("Finished initialising Kafkatorio Global variables")
end
return ____exports

View file

@ -1,46 +0,0 @@
local ____lualib = require("lualib_bundle")
local __TS__Class = ____lualib.__TS__Class
local __TS__StringReplaceAll = ____lualib.__TS__StringReplaceAll
local __TS__New = ____lualib.__TS__New
local ____exports = {}
____exports.KafkatorioSettingsConfig = __TS__Class()
local KafkatorioSettingsConfig = ____exports.KafkatorioSettingsConfig
KafkatorioSettingsConfig.name = "KafkatorioSettingsConfig"
function KafkatorioSettingsConfig.prototype.____constructor(self)
end
function KafkatorioSettingsConfig.prototype.getEventCacheExpirationTicks(self, packet)
local settingName = ____exports.KafkatorioSettingsConfig:cacheDurationSettingName(packet.type)
local seconds = settings.global[settingName].value
return seconds * 60
end
function KafkatorioSettingsConfig.prototype.initialiseSettings(self, data)
for ____type in pairs(____exports.KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds) do
data:extend({____exports.KafkatorioSettingsConfig:createDefaultCacheDuration(____type)})
end
end
function KafkatorioSettingsConfig.createDefaultCacheDuration(self, ____type, defaultExpirationSeconds)
if defaultExpirationSeconds == nil then
defaultExpirationSeconds = ____exports.KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[____type]
end
return {
type = "double-setting",
name = ____exports.KafkatorioSettingsConfig:cacheDurationSettingName(____type),
setting_type = "runtime-global",
default_value = defaultExpirationSeconds,
minimum_value = 0.25,
maximum_value = 120
}
end
function KafkatorioSettingsConfig.cacheDurationSettingName(self, ____type)
return "kafkatorio:cache-expiration-seconds_" .. __TS__StringReplaceAll(____type, ".", "-")
end
KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds = {
["kafkatorio.packet.keyed.PlayerUpdate"] = 0.5,
["kafkatorio.packet.keyed.MapChunkTileUpdate"] = 30,
["kafkatorio.packet.keyed.MapChunkEntityUpdate"] = 30,
["kafkatorio.packet.keyed.MapChunkResourceUpdate"] = 30,
["kafkatorio.packet.keyed.EntityUpdate"] = 5
}
local KafkatorioSettings = __TS__New(____exports.KafkatorioSettingsConfig)
____exports.default = KafkatorioSettings
return ____exports

View file

@ -1,5 +0,0 @@
local ____exports = {}
local ____KafkatorioSettings = require("main.settings.KafkatorioSettings")
local KafkatorioSettings = ____KafkatorioSettings.default
KafkatorioSettings:initialiseSettings(data)
return ____exports

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

View file

@ -1,9 +0,0 @@
{
"name": "@mod.name@",
"version": "@project.version@",
"title": "@mod.title@",
"description": "@mod.description@",
"author": "@author.email@",
"factorio_version": "@factorio.version@",
"dependencies": []
}

View file

Before

Width:  |  Height:  |  Size: 8 KiB

After

Width:  |  Height:  |  Size: 8 KiB

Before After
Before After

View file

@ -40,7 +40,7 @@ script.on_event(defines.events.on_tick, (event: OnTickEvent) => {
if (isEventType(event, defines.events.on_chunk_generated)) { if (isEventType(event, defines.events.on_chunk_generated)) {
let eName = Converters.eventNameString(event.name) let eName = Converters.eventNameString(event.name)
log(`[on_tick:${event.tick}] dequed event ${eName}, delay ${i}`) log(`[on_tick:${event.tick}] dequeued event ${eName}, delay ${i}`)
MapChunkUpdate.handleChunkGeneratedEvent(event, i) MapChunkUpdate.handleChunkGeneratedEvent(event, i)
i += 1 i += 1
} }

View file

@ -18,6 +18,7 @@ dependencies {
implementation(platform(projects.modules.versionsPlatform)) implementation(platform(projects.modules.versionsPlatform))
implementation(libs.kafka.streams) implementation(libs.kafka.streams)
implementation(kotlin("reflect"))
testImplementation(libs.kafka.streamsTestUtils) testImplementation(libs.kafka.streamsTestUtils)

View file

@ -1,6 +1,4 @@
import dev.adamko.gradle.factorio.FactorioModPlugin import dev.adamko.gradle.factorio.FactorioModPlugin
import dev.adamko.gradle.factorio.factorioModAttributes
import kafkatorio.extensions.not
import kafkatorio.tasks.ProcessRunningSpec import kafkatorio.tasks.ProcessRunningSpec
import org.gradle.kotlin.dsl.support.serviceOf import org.gradle.kotlin.dsl.support.serviceOf
import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs
@ -10,7 +8,7 @@ plugins {
id("dev.adamko.factorio-mod") id("dev.adamko.factorio-mod")
} }
description = "Start the Factorio game client" description = "Manage the Factorio game client"
val clientModsDirectory: DirectoryProperty = objects.directoryProperty().apply { val clientModsDirectory: DirectoryProperty = objects.directoryProperty().apply {
val modDir = File("""D:\Users\Adam\AppData\Roaming\Factorio\mods""") val modDir = File("""D:\Users\Adam\AppData\Roaming\Factorio\mods""")
@ -18,69 +16,15 @@ val clientModsDirectory: DirectoryProperty = objects.directoryProperty().apply {
set(modDir) set(modDir)
} }
} }
val factorioGameId = "427520"
val steamExe: RegularFileProperty = objects.fileProperty().apply {
val steam = File("""C:\Program Files (x86)\Steam\steam.exe""")
if (steam.exists()) {
set(steam)
}
}
//val factorioMod: Configuration by configurations.creating {
// asConsumer()
// factorioModAttributes(objects)
//}
dependencies { dependencies {
factorioMod(projects.modules.eventsMod) factorioMod(projects.modules.eventsMod)
} }
//<editor-fold desc="Mod deployment tasks">
val deployModToLocalClient by tasks.registering(Copy::class) {
description = "Copy the mod to the Factorio client"
group = FactorioModPlugin.TASK_GROUP
val clientModsDirectory123 = clientModsDirectory
onlyIf { clientModsDirectory123.orNull?.asFile?.exists() == true }
from(configurations.factorioMod.map { it.incoming.artifactView { lenient(true) }.files })
into(clientModsDirectory)
doLast {
logger.lifecycle("Copying mod from ${source.files} to $destinationDir")
}
}
//</editor-fold>
//<editor-fold desc="Factorio client lifecycle tasks">
fun ExecOperations.isFactorioRunning(): Spec<Task> = ProcessRunningSpec(this, "factorio.exe") fun ExecOperations.isFactorioRunning(): Spec<Task> = ProcessRunningSpec(this, "factorio.exe")
val clientLaunch by tasks.registering(Exec::class) {
description = "Run local Factorio Steam game client"
group = FactorioModPlugin.TASK_GROUP
val steamExe123 = steamExe
val clientModsDirectory444 = clientModsDirectory
onlyIf(!serviceOf<ExecOperations>().isFactorioRunning())
onlyIf { steamExe123.orNull?.asFile?.exists() == true }
onlyIf { clientModsDirectory444.orNull?.asFile?.exists() == true }
dependsOn(deployModToLocalClient)
mustRunAfter(clientKill, ":modules:infra-factorio-server:processRun")
commandLine = parseSpaceSeparatedArgs(
// """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working
// """explorer "steam://run/$factorioGameId//--mp-connect localhost/" """ // works! But has annoying pop-up
""" ${steamExe.asFile.orNull?.canonicalPath} -applaunch $factorioGameId --mp-connect localhost --mod-directory ${clientModsDirectory.asFile.orNull?.canonicalPath} """
)
doFirst { logger.lifecycle("Launching factorio.exe") }
}
val clientKill by tasks.registering(Exec::class) { val clientKill by tasks.registering(Exec::class) {
description = "Stop the local Factorio Steam game client" description = "Stop the local Factorio Steam game client"
group = FactorioModPlugin.TASK_GROUP group = FactorioModPlugin.TASK_GROUP
@ -90,19 +34,18 @@ val clientKill by tasks.registering(Exec::class) {
commandLine = parseSpaceSeparatedArgs(""" taskkill /im factorio.exe """) commandLine = parseSpaceSeparatedArgs(""" taskkill /im factorio.exe """)
doFirst { logger.lifecycle("Killing factorio.exe") } doFirst { logger.lifecycle("Killing factorio.exe") }
} }
//</editor-fold>
tasks.register(FactorioModPlugin.PUBLISH_MOD_LOCAL_TASK_NAME) { tasks.register(FactorioModPlugin.PUBLISH_MOD_LOCAL_TASK_NAME) {
group = FactorioModPlugin.TASK_GROUP group = FactorioModPlugin.TASK_GROUP
dependsOn(deployModToLocalClient) // dependsOn(deployModToLocalClient)
} }
tasks.processRun { tasks.processRun {
dependsOn( dependsOn(
deployModToLocalClient, // deployModToLocalClient,
clientLaunch, tasks.launchFactorioClient,
) )
} }

View file

@ -3,7 +3,7 @@ import dev.adamko.gradle.factorio.FactorioModPlugin
plugins { plugins {
id("kafkatorio.conventions.base") id("kafkatorio.conventions.base")
id("dev.adamko.geedeecee") id("dev.adamko.geedeecee")
id("dev.adamko.factorio-mod") id("dev.adamko.factorio-mod-library")
idea idea
} }
@ -12,19 +12,9 @@ geedeecee {
srcDir.set(layout.projectDirectory.dir("src")) srcDir.set(layout.projectDirectory.dir("src"))
} }
//val dockerSrcDir: Directory by extra
//val factorioServerDataDir: Directory = dockerSrcDir.dir("factorio-server")
val factorioServerDataDir: DirectoryProperty = objects.directoryProperty() val factorioServerDataDir: DirectoryProperty = objects.directoryProperty()
.convention(geedeecee.srcDir.dir("factorio-server")) .convention(geedeecee.srcDir.dir("factorio-server"))
//val factorioMod: Configuration by configurations.creating {
// asConsumer()
// factorioModAttributes(objects)
//}
dependencies { dependencies {
factorioMod(projects.modules.eventsMod) factorioMod(projects.modules.eventsMod)
} }
@ -61,13 +51,15 @@ tasks.dockerComposeUp {
} }
val kafkatorioServerToken: String by project val kafkatorioServerToken: String? by project
tasks.dockerComposeEnvUpdate { tasks.dockerComposeEnvUpdate {
envProperties { envProperties {
put("FACTORIO_VERSION", libs.versions.factorio) put("FACTORIO_VERSION", libs.versions.factorio)
put("KAFKATORIO_TOKEN", kafkatorioServerToken) kafkatorioServerToken?.let { token ->
put("KAFKATORIO_TOKEN", token)
}
} }
} }

View file

@ -18,6 +18,7 @@ import io.kvision.maps.externals.leaflet.geo.LatLng
import io.kvision.maps.externals.leaflet.layer.LayerGroup import io.kvision.maps.externals.leaflet.layer.LayerGroup
import io.kvision.maps.externals.leaflet.layer.tile.TileLayer import io.kvision.maps.externals.leaflet.layer.tile.TileLayer
import io.kvision.utils.px import io.kvision.utils.px
import js.core.jso
import kotlinx.browser.document import kotlinx.browser.document
import kotlinx.browser.window import kotlinx.browser.window
import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineName
@ -30,7 +31,6 @@ import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.js.jso
import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLElement
import org.w3c.dom.Image import org.w3c.dom.Image
import org.w3c.dom.asList import org.w3c.dom.asList

View file

@ -5,7 +5,7 @@ import dev.adamko.kafkatorio.schema.common.Tick
import dev.adamko.kafkatorio.schema.packets.PlayerUpdate import dev.adamko.kafkatorio.schema.packets.PlayerUpdate
import io.kvision.maps.Maps import io.kvision.maps.Maps
import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker import io.kvision.maps.externals.leaflet.layer.vector.CircleMarker
import kotlinx.js.jso import js.core.jso
data class PlayerState( data class PlayerState(
val index: PlayerIndex, val index: PlayerIndex,

View file

@ -48,7 +48,9 @@ include(
) )
//enableFeaturePreview(org.gradle.api.internal.FeaturePreviews.Feature.TYPESAFE_PROJECT_ACCESSORS.name)
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
enableFeaturePreview("STABLE_CONFIGURATION_CACHE")
//apply(from = "./buildSrc/repositories.settings.gradle.kts") //apply(from = "./buildSrc/repositories.settings.gradle.kts")