it is literally working
This commit is contained in:
parent
841f07c847
commit
a0c330384a
17 changed files with 499 additions and 63 deletions
11
README.md
11
README.md
|
|
@ -42,6 +42,14 @@ is provided.
|
||||||
|
|
||||||
* https://jbrandhorst.com/post/go-protobuf-tips/
|
* https://jbrandhorst.com/post/go-protobuf-tips/
|
||||||
|
|
||||||
|
|
||||||
|
##### wasm
|
||||||
|
|
||||||
|
kt -> wasm -> lua?
|
||||||
|
kt-flatbuffers -> wasm -> lua?
|
||||||
|
|
||||||
|
https://www.npmjs.com/package/wasm2lua?activeTab=readme
|
||||||
|
|
||||||
##### flatbuffers
|
##### flatbuffers
|
||||||
|
|
||||||
https://github.com/dvidelabs/flatcc
|
https://github.com/dvidelabs/flatcc
|
||||||
|
|
@ -56,6 +64,3 @@ https://github.com/dvidelabs/flatcc
|
||||||
|
|
||||||
https://www.zash.se/lua-cbor.html
|
https://www.zash.se/lua-cbor.html
|
||||||
https://code.zash.se/lua-cbor/archive/68b3a36d0816.tar.gz
|
https://code.zash.se/lua-cbor/archive/68b3a36d0816.tar.gz
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,13 @@
|
||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@babel/runtime@^7.9.2":
|
||||||
|
version "7.16.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.5.tgz#7f3e34bf8bdbbadf03fbb7b1ea0d929569c9487a"
|
||||||
|
integrity sha512-TXWihFIS3Pyv5hzR7j6ihmeLkZfrXGxAr5UfSl8CHf+6q/wpiYDkUau0czckpYG8QmnCIuPpdLtuA9VmuGGyMA==
|
||||||
|
dependencies:
|
||||||
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
"@discoveryjs/json-ext@^0.5.0":
|
"@discoveryjs/json-ext@^0.5.0":
|
||||||
version "0.5.6"
|
version "0.5.6"
|
||||||
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f"
|
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz#d5e0706cf8c6acd8c6032f8d54070af261bbbb2f"
|
||||||
|
|
@ -81,6 +88,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83"
|
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83"
|
||||||
integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==
|
integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==
|
||||||
|
|
||||||
|
"@types/geojson@*", "@types/geojson@7946.0.8":
|
||||||
|
version "7946.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.8.tgz#30744afdb385e2945e22f3b033f897f76b1f12ca"
|
||||||
|
integrity sha512-1rkryxURpr6aWP7R786/UQOkJ3PcpQiWkAXBmdWc7ryFWqN6a4xfK7BtjXvFBKO9LjQ+MWQSWxYeZX1OApnArA==
|
||||||
|
|
||||||
"@types/glob@5 - 7":
|
"@types/glob@5 - 7":
|
||||||
version "7.2.0"
|
version "7.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
|
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
|
||||||
|
|
@ -101,6 +113,13 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
|
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
|
||||||
integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
|
integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
|
||||||
|
|
||||||
|
"@types/leaflet@^1.7.7":
|
||||||
|
version "1.7.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/leaflet/-/leaflet-1.7.7.tgz#3c9f629126e03405ed68cc1aa395e32df3312376"
|
||||||
|
integrity sha512-5/nNqTviSqUwPxbS3PlHl8ODjfnlpOXSFtUAi7dexnisO8E3pfyotChRY/hlIYGvbBiBcKNd6V18xA8O4OpHiQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/geojson" "*"
|
||||||
|
|
||||||
"@types/minimatch@*":
|
"@types/minimatch@*":
|
||||||
version "3.0.5"
|
version "3.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
|
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
|
||||||
|
|
@ -949,6 +968,14 @@ dukat@0.5.8-rc.3:
|
||||||
google-protobuf "3.12.2"
|
google-protobuf "3.12.2"
|
||||||
typescript "3.9.5"
|
typescript "3.9.5"
|
||||||
|
|
||||||
|
dukat@0.5.8-rc.4:
|
||||||
|
version "0.5.8-rc.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.4.tgz#90384dcb50b14c26f0e99dae92b2dea44f5fce21"
|
||||||
|
integrity sha512-ZnMt6DGBjlVgK2uQamXfd7uP/AxH7RqI0BL9GLrrJb2gKdDxvJChWy+M9AQEaL+7/6TmxzJxFOsRiInY9oGWTA==
|
||||||
|
dependencies:
|
||||||
|
google-protobuf "3.12.2"
|
||||||
|
typescript "3.9.5"
|
||||||
|
|
||||||
ee-first@1.1.1:
|
ee-first@1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||||
|
|
@ -1280,6 +1307,11 @@ function-bind@^1.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||||
|
|
||||||
|
geojson@^0.5.0:
|
||||||
|
version "0.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/geojson/-/geojson-0.5.0.tgz#3cd6c96399be65b56ee55596116fe9191ce701c0"
|
||||||
|
integrity sha1-PNbJY5m+ZbVu5VWWEW/pGRznAcA=
|
||||||
|
|
||||||
get-caller-file@^2.0.5:
|
get-caller-file@^2.0.5:
|
||||||
version "2.0.5"
|
version "2.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||||
|
|
@ -1845,6 +1877,11 @@ kvision-assets@^5.0.7:
|
||||||
resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.7.tgz#e6dc3e28a2d244b4c89318b060d3e7e337c15495"
|
resolved "https://registry.yarnpkg.com/kvision-assets/-/kvision-assets-5.0.7.tgz#e6dc3e28a2d244b4c89318b060d3e7e337c15495"
|
||||||
integrity sha512-szoL8ixFRTivLkbnmkWFjGJMk3bsUW/loUS5QfWThPwFnyFEw8ht3eBUrJ0V51Rn/WaJbVoPvY4SfIaiNu13bg==
|
integrity sha512-szoL8ixFRTivLkbnmkWFjGJMk3bsUW/loUS5QfWThPwFnyFEw8ht3eBUrJ0V51Rn/WaJbVoPvY4SfIaiNu13bg==
|
||||||
|
|
||||||
|
leaflet@^1.7.1:
|
||||||
|
version "1.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.7.1.tgz#10d684916edfe1bf41d688a3b97127c0322a2a19"
|
||||||
|
integrity sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw==
|
||||||
|
|
||||||
loader-runner@^4.2.0:
|
loader-runner@^4.2.0:
|
||||||
version "4.2.0"
|
version "4.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
|
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
|
||||||
|
|
@ -2430,6 +2467,23 @@ rechoir@^0.7.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
resolve "^1.9.0"
|
resolve "^1.9.0"
|
||||||
|
|
||||||
|
redux-thunk@^2.4.0:
|
||||||
|
version "2.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.1.tgz#0dd8042cf47868f4b29699941de03c9301a75714"
|
||||||
|
integrity sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==
|
||||||
|
|
||||||
|
redux@^4.1.2:
|
||||||
|
version "4.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.2.tgz#140f35426d99bb4729af760afcf79eaaac407104"
|
||||||
|
integrity sha512-SH8PglcebESbd/shgf6mii6EIoRM0zrQyjcuQ+ojmfxjTtE0z9Y8pa62iA/OJ58qjP6j27uyW4kUF4jl/jd6sw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.9.2"
|
||||||
|
|
||||||
|
regenerator-runtime@^0.13.4:
|
||||||
|
version "0.13.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
||||||
|
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
|
||||||
|
|
||||||
regexp.prototype.flags@^1.2.0:
|
regexp.prototype.flags@^1.2.0:
|
||||||
version "1.3.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26"
|
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26"
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,8 @@ camel-kafkaConnectors = "0.11.0"
|
||||||
http4k = "4.17.6.0"
|
http4k = "4.17.6.0"
|
||||||
kafka = "3.0.0"
|
kafka = "3.0.0"
|
||||||
kotlinx-serialization = "1.3.2"
|
kotlinx-serialization = "1.3.2"
|
||||||
kvision = "5.6.1"
|
#kvision = "5.6.1"
|
||||||
|
kvision = "5.6.2-SNAPSHOT"
|
||||||
log4j2 = "2.14.1"
|
log4j2 = "2.14.1"
|
||||||
qosLogback = "1.2.5"
|
qosLogback = "1.2.5"
|
||||||
slf4j = "1.7.30"
|
slf4j = "1.7.30"
|
||||||
|
|
@ -50,8 +51,12 @@ kotlinx-serialization-bom = { group = "org.jetbrains.kotlinx", name = "kotlinx-
|
||||||
kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" }
|
kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core" }
|
||||||
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" }
|
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json" }
|
||||||
kotlinx-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", version = "0.37.0" }
|
kotlinx-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", version = "0.37.0" }
|
||||||
|
|
||||||
kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.6.0" }
|
kotlinx-coroutines = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.6.0" }
|
||||||
|
|
||||||
kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.3" }
|
kotlinx-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.7.3" }
|
||||||
|
kotlinx-nodejs = { group = "org.jetbrains.kotlinx", name = "kotlinx-nodejs", version = "0.0.7" }
|
||||||
|
|
||||||
|
|
||||||
## http4k ##
|
## http4k ##
|
||||||
http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" }
|
http4k-bom = { group = "org.http4k", name = "http4k-bom", version.ref = "http4k" }
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,13 @@ interface FactorioEvent<T extends FactorioObjectData> {
|
||||||
tick: uint;
|
tick: uint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Colour {
|
||||||
|
alpha: float;
|
||||||
|
blue: float;
|
||||||
|
green: float;
|
||||||
|
red: float;
|
||||||
|
}
|
||||||
|
|
||||||
interface PositionData {
|
interface PositionData {
|
||||||
x: double;
|
x: double;
|
||||||
y: double;
|
y: double;
|
||||||
|
|
@ -19,6 +26,9 @@ interface PositionData {
|
||||||
interface PlayerData extends FactorioObjectData {
|
interface PlayerData extends FactorioObjectData {
|
||||||
associated_characters_unit_numbers: uint[];
|
associated_characters_unit_numbers: uint[];
|
||||||
character_unit_number: uint | null;
|
character_unit_number: uint | null;
|
||||||
|
chat_colour: Colour;
|
||||||
|
colour: Colour;
|
||||||
|
last_online: uint;
|
||||||
name: string;
|
name: string;
|
||||||
object_name: string;
|
object_name: string;
|
||||||
position: PositionData;
|
position: PositionData;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ export namespace Serdes {
|
||||||
character_unit_number: player.character?.unit_number ?? null,
|
character_unit_number: player.character?.unit_number ?? null,
|
||||||
associated_characters_unit_numbers: charIds,
|
associated_characters_unit_numbers: charIds,
|
||||||
position: positionTableToTable(player.position),
|
position: positionTableToTable(player.position),
|
||||||
|
colour: mapColour(player.color),
|
||||||
|
chat_colour: mapColour(player.chat_color),
|
||||||
|
last_online: player.last_online
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,4 +65,14 @@ export namespace Serdes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function mapColour(color: Color): Colour {
|
||||||
|
color = (color as ColorTable)
|
||||||
|
return {
|
||||||
|
red: color.r ?? 0,
|
||||||
|
green: color.g ?? 0,
|
||||||
|
blue: color.b ?? 0,
|
||||||
|
alpha: color.a ?? 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,9 @@ kotlin {
|
||||||
|
|
||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project.dependencies.enforcedPlatform(libs.kotlin.bom))
|
implementation(project.dependencies.platform(libs.kotlin.bom))
|
||||||
|
|
||||||
implementation(project.dependencies.enforcedPlatform(libs.kotlinx.serialization.bom))
|
implementation(project.dependencies.platform(libs.kotlinx.serialization.bom))
|
||||||
implementation(libs.kotlinx.serialization.core)
|
implementation(libs.kotlinx.serialization.core)
|
||||||
implementation(libs.kotlinx.serialization.json)
|
implementation(libs.kotlinx.serialization.json)
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ kotlin {
|
||||||
|
|
||||||
implementation(kotlin("test"))
|
implementation(kotlin("test"))
|
||||||
|
|
||||||
implementation(project.dependencies.enforcedPlatform(libs.kotest.bom))
|
implementation(project.dependencies.platform(libs.kotest.bom))
|
||||||
implementation("io.kotest:kotest-assertions-core")
|
implementation("io.kotest:kotest-assertions-core")
|
||||||
implementation("io.kotest:kotest-property")
|
implementation("io.kotest:kotest-property")
|
||||||
implementation("io.kotest:kotest-assertions-json")
|
implementation("io.kotest:kotest-assertions-json")
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,18 @@ import kotlinx.serialization.json.JsonClassDiscriminator
|
||||||
@Serializable
|
@Serializable
|
||||||
data class FactorioEvent<out T : FactorioObjectData>(
|
data class FactorioEvent<out T : FactorioObjectData>(
|
||||||
/** the initial Factorio event ({defines.events}) trigger */
|
/** the initial Factorio event ({defines.events}) trigger */
|
||||||
@SerialName("event_type") val eventType: String,
|
@SerialName("event_type")
|
||||||
|
val eventType: String,
|
||||||
/** Schema versioning */
|
/** Schema versioning */
|
||||||
@SerialName("mod_version") val modVersion: String,
|
@SerialName("mod_version")
|
||||||
@SerialName("factorio_version") val factorioVersion: String,
|
val modVersion: String,
|
||||||
|
@SerialName("factorio_version")
|
||||||
|
val factorioVersion: String,
|
||||||
/** game time */
|
/** game time */
|
||||||
@SerialName("tick") val tick: UInt,
|
@SerialName("tick")
|
||||||
@SerialName("data") val data: T
|
val tick: UInt,
|
||||||
|
@SerialName("data")
|
||||||
|
val data: T
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -53,10 +58,20 @@ sealed class FactorioObjectData {
|
||||||
@SerialName("LuaPlayer")
|
@SerialName("LuaPlayer")
|
||||||
data class PlayerData(
|
data class PlayerData(
|
||||||
@Serializable(with = ListAsObjectSerializer::class)
|
@Serializable(with = ListAsObjectSerializer::class)
|
||||||
@SerialName("associated_characters_unit_numbers") val associatedCharactersUnitNumbers: List<UInt>,
|
@SerialName("associated_characters_unit_numbers")
|
||||||
@SerialName("character_unit_number") val characterUnitNumber: UInt?,
|
val associatedCharactersUnitNumbers: List<UInt>,
|
||||||
@SerialName("name") val name: String,
|
@SerialName("character_unit_number")
|
||||||
@SerialName("position") val position: PositionData,
|
val characterUnitNumber: UInt?,
|
||||||
|
@SerialName("name")
|
||||||
|
val name: String,
|
||||||
|
@SerialName("position")
|
||||||
|
val position: PositionData,
|
||||||
|
@SerialName("colour")
|
||||||
|
val colour: Colour,
|
||||||
|
@SerialName("chat_colour")
|
||||||
|
val chatColour: Colour,
|
||||||
|
@SerialName("last_online")
|
||||||
|
val lastOnline: UInt,
|
||||||
) : FactorioObjectData() {
|
) : FactorioObjectData() {
|
||||||
@Transient
|
@Transient
|
||||||
override val objectName: String = "LuaPlayer"
|
override val objectName: String = "LuaPlayer"
|
||||||
|
|
@ -65,16 +80,25 @@ data class PlayerData(
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("LuaEntity")
|
@SerialName("LuaEntity")
|
||||||
data class EntityData(
|
data class EntityData(
|
||||||
@SerialName("active") val active: Boolean,
|
@SerialName("active")
|
||||||
@SerialName("health") val health: Double?,
|
val active: Boolean,
|
||||||
@SerialName("health_ratio") val healthRatio: Double,
|
@SerialName("health")
|
||||||
@SerialName("name") val name: String,
|
val health: Double?,
|
||||||
@SerialName("position") val position: PositionData,
|
@SerialName("health_ratio")
|
||||||
@SerialName("surface_index") val surfaceIndex: Int,
|
val healthRatio: Double,
|
||||||
@SerialName("type") val type: String,
|
@SerialName("name")
|
||||||
@SerialName("unit_number") val unitNumber: UInt? = null,
|
val name: String,
|
||||||
|
@SerialName("position")
|
||||||
|
val position: PositionData,
|
||||||
|
@SerialName("surface_index")
|
||||||
|
val surfaceIndex: Int,
|
||||||
|
@SerialName("type")
|
||||||
|
val type: String,
|
||||||
|
@SerialName("unit_number")
|
||||||
|
val unitNumber: UInt? = null,
|
||||||
|
|
||||||
@SerialName("player_index") val playerIndex: UInt? = null,
|
@SerialName("player_index")
|
||||||
|
val playerIndex: UInt? = null,
|
||||||
) : FactorioObjectData() {
|
) : FactorioObjectData() {
|
||||||
@Transient
|
@Transient
|
||||||
override val objectName: String = "LuaEntity"
|
override val objectName: String = "LuaEntity"
|
||||||
|
|
@ -83,9 +107,12 @@ data class EntityData(
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("LuaSurface")
|
@SerialName("LuaSurface")
|
||||||
data class SurfaceData(
|
data class SurfaceData(
|
||||||
@SerialName("daytime") val daytime: Double,
|
@SerialName("daytime")
|
||||||
@SerialName("index") val index: UInt,
|
val daytime: Double,
|
||||||
@SerialName("name") val name: String,
|
@SerialName("index")
|
||||||
|
val index: UInt,
|
||||||
|
@SerialName("name")
|
||||||
|
val name: String,
|
||||||
) : FactorioObjectData() {
|
) : FactorioObjectData() {
|
||||||
@Transient
|
@Transient
|
||||||
override val objectName: String = "LuaSurface"
|
override val objectName: String = "LuaSurface"
|
||||||
|
|
@ -93,6 +120,32 @@ data class SurfaceData(
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class PositionData(
|
data class PositionData(
|
||||||
@SerialName("x") val x: Double,
|
val x: Double,
|
||||||
@SerialName("y") val y: Double,
|
val y: Double,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Red, green, blue and alpha values, all in range `[0, 1]` or all in range `[0, 255]` if any
|
||||||
|
* value is > 1.
|
||||||
|
*
|
||||||
|
* All values here are optional. Color channels default to 0, the alpha channel defaults to 1.
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
data class Colour(
|
||||||
|
val red: Float = 0f,
|
||||||
|
val green: Float = 0f,
|
||||||
|
val blue: Float = 0f,
|
||||||
|
val alpha: Float = 1f,
|
||||||
|
) {
|
||||||
|
/** True if any value is greater than 1, so the values are hexadecimal. */
|
||||||
|
fun isDecimal(): Boolean {
|
||||||
|
return red > 1f
|
||||||
|
|| green > 1f
|
||||||
|
|| blue > 1f
|
||||||
|
|| alpha > 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
/** True if all values are between `[0..1]`. */
|
||||||
|
fun isPercentage(): Boolean = !isDecimal()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@ class FactorioEventTest : BehaviorSpec({
|
||||||
"position": {
|
"position": {
|
||||||
"x": -3.5703125,
|
"x": -3.5703125,
|
||||||
"y": 29.75
|
"y": 29.75
|
||||||
}
|
},
|
||||||
|
"last_online": 123
|
||||||
},
|
},
|
||||||
"event_type": "on_player_joined_game",
|
"event_type": "on_player_joined_game",
|
||||||
"mod_version": "0.0.4",
|
"mod_version": "0.0.4",
|
||||||
|
|
@ -41,7 +42,10 @@ class FactorioEventTest : BehaviorSpec({
|
||||||
position = PositionData(
|
position = PositionData(
|
||||||
x = -3.5703125,
|
x = -3.5703125,
|
||||||
y = 29.75
|
y = 29.75
|
||||||
)
|
),
|
||||||
|
colour = Colour(),
|
||||||
|
chatColour = Colour(),
|
||||||
|
lastOnline = 123u
|
||||||
),
|
),
|
||||||
eventType = "on_player_joined_game",
|
eventType = "on_player_joined_game",
|
||||||
modVersion = "0.0.4",
|
modVersion = "0.0.4",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
|
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
|
import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("dev.adamko.kafkatorio.lang.kotlin-js")
|
id("dev.adamko.kafkatorio.lang.kotlin-js")
|
||||||
kotlin("plugin.serialization")
|
kotlin("plugin.serialization")
|
||||||
// kotlin("js") // version kotlinVersion
|
|
||||||
id("io.kvision") version "5.6.1"
|
id("io.kvision") version "5.6.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -13,7 +13,7 @@ kotlin {
|
||||||
browser {
|
browser {
|
||||||
runTask {
|
runTask {
|
||||||
outputFileName = "main.bundle.js"
|
outputFileName = "main.bundle.js"
|
||||||
sourceMaps = false
|
sourceMaps = true
|
||||||
devServer = KotlinWebpackConfig.DevServer(
|
devServer = KotlinWebpackConfig.DevServer(
|
||||||
open = false,
|
open = false,
|
||||||
port = 3000,
|
port = 3000,
|
||||||
|
|
@ -37,31 +37,54 @@ kotlin {
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
val kvisionVersion: String = libs.versions.kvision.get()
|
|
||||||
|
all {
|
||||||
|
languageSettings.optIn("kotlin.RequiresOptIn")
|
||||||
|
languageSettings.optIn("kotlinx.serialization.ExperimentalSerializationApi")
|
||||||
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
|
implementation(projects.modules.eventsSchema)
|
||||||
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7")
|
implementation("org.jetbrains.kotlinx:kotlinx-nodejs:0.0.7")
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-html:0.7.3")
|
||||||
|
|
||||||
implementation("io.kvision:kvision:$kvisionVersion")
|
kvision("kvision")
|
||||||
implementation("io.kvision:kvision-bootstrap:$kvisionVersion")
|
kvision("kvision-bootstrap")
|
||||||
implementation("io.kvision:kvision-bootstrap-css:$kvisionVersion")
|
kvision("kvision-bootstrap-css")
|
||||||
implementation("io.kvision:kvision-bootstrap-icons:$kvisionVersion")
|
kvision("kvision-bootstrap-icons")
|
||||||
implementation("io.kvision:kvision-fontawesome:$kvisionVersion")
|
kvision("kvision-fontawesome")
|
||||||
implementation("io.kvision:kvision-state:$kvisionVersion")
|
kvision("kvision-state")
|
||||||
implementation("io.kvision:kvision-chart:$kvisionVersion")
|
kvision("kvision-chart")
|
||||||
|
kvision("kvision-maps")
|
||||||
|
kvision("kvision-redux")
|
||||||
|
kvision("kvision-state-flow")
|
||||||
|
|
||||||
|
implementation(libs.kotlinx.coroutines)
|
||||||
}
|
}
|
||||||
|
|
||||||
val webDir = file("src/main/web")
|
val webDir = file("src/main/web")
|
||||||
resources.srcDir(webDir)
|
resources.srcDir(webDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
test {
|
test {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("test-js"))
|
implementation(kotlin("test-js"))
|
||||||
implementation("io.kvision:kvision-testutils:$kvisionVersion")
|
|
||||||
|
kvision("kvision-testutils")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun KotlinDependencyHandler.kvision(
|
||||||
|
module: String,
|
||||||
|
version: Provider<String> = libs.versions.kvision,
|
||||||
|
configure: ExternalModuleDependency.() -> Unit = {
|
||||||
|
isChanging = true
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
implementation("io.kvision:$module:${version.get()}", configure)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,73 @@
|
||||||
package dev.adamko.kafkatorio.webmap
|
package dev.adamko.kafkatorio.webmap
|
||||||
|
|
||||||
import io.kvision.Application
|
import io.kvision.Application
|
||||||
import io.kvision.CoreModule
|
|
||||||
import io.kvision.BootstrapModule
|
|
||||||
import io.kvision.BootstrapCssModule
|
import io.kvision.BootstrapCssModule
|
||||||
import io.kvision.BootstrapIconsModule
|
import io.kvision.BootstrapIconsModule
|
||||||
import io.kvision.FontAwesomeModule
|
import io.kvision.BootstrapModule
|
||||||
import io.kvision.ChartModule
|
import io.kvision.ChartModule
|
||||||
|
import io.kvision.CoreModule
|
||||||
|
import io.kvision.FontAwesomeModule
|
||||||
import io.kvision.html.div
|
import io.kvision.html.div
|
||||||
|
import io.kvision.maps.Maps
|
||||||
import io.kvision.module
|
import io.kvision.module
|
||||||
import io.kvision.panel.root
|
import io.kvision.panel.root
|
||||||
|
import io.kvision.redux.ReduxStore
|
||||||
import io.kvision.startApplication
|
import io.kvision.startApplication
|
||||||
|
|
||||||
class App : Application() {
|
|
||||||
override fun start() {
|
class App(
|
||||||
root("kvapp") {
|
reduxStore: ReduxStore<FactorioGameState, FactorioUpdate>,
|
||||||
div("Hello world")
|
wsService: WebsocketService
|
||||||
}
|
) : Application() {
|
||||||
|
private var appState: MutableMap<String, Any> = mutableMapOf()
|
||||||
|
|
||||||
|
var reduxStore: ReduxStore<FactorioGameState, FactorioUpdate> by appState
|
||||||
|
var wsService: WebsocketService by appState
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.reduxStore = reduxStore
|
||||||
|
this.wsService = wsService
|
||||||
|
}
|
||||||
|
|
||||||
|
private val kvMaps: Maps
|
||||||
|
get() = reduxStore.getState().kvMaps
|
||||||
|
|
||||||
|
override fun start(state: Map<String, Any>) {
|
||||||
|
this.appState = state.toMutableMap()
|
||||||
|
|
||||||
|
root("kvapp") {
|
||||||
|
div("Kafkatorio Web Map")
|
||||||
|
add(kvMaps)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose(): Map<String, Any> {
|
||||||
|
return appState
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
startApplication(
|
startApplication(
|
||||||
::App,
|
{
|
||||||
module.hot,
|
val reduxStore = createFactorioReduxStore()
|
||||||
BootstrapModule,
|
val wsService = WebsocketService(
|
||||||
BootstrapCssModule,
|
"ws://localhost:9073/ws",
|
||||||
BootstrapIconsModule,
|
reduxStore,
|
||||||
FontAwesomeModule,
|
)
|
||||||
ChartModule,
|
|
||||||
CoreModule
|
App(
|
||||||
)
|
reduxStore = reduxStore,
|
||||||
|
wsService = wsService
|
||||||
|
)
|
||||||
|
},
|
||||||
|
module.hot,
|
||||||
|
BootstrapModule,
|
||||||
|
BootstrapCssModule,
|
||||||
|
BootstrapIconsModule,
|
||||||
|
FontAwesomeModule,
|
||||||
|
ChartModule,
|
||||||
|
CoreModule
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package dev.adamko.kafkatorio.webmap
|
||||||
|
|
||||||
|
import dev.adamko.kafkatorio.events.schema.Colour
|
||||||
|
import dev.adamko.kafkatorio.events.schema.PlayerData
|
||||||
|
import externals.leaflet.geo.LatLng
|
||||||
|
import io.kvision.maps.Maps
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
||||||
|
fun Colour.toHexString(includeAlpha: Boolean = false): String {
|
||||||
|
|
||||||
|
val hexConverter: Float.() -> String = if (isDecimal()) {
|
||||||
|
Float::decimalToHex
|
||||||
|
} else {
|
||||||
|
Float::percentageToHex
|
||||||
|
}
|
||||||
|
|
||||||
|
val length = if (includeAlpha) 9 else 7
|
||||||
|
return buildString(length) {
|
||||||
|
append('#')
|
||||||
|
append(red.hexConverter())
|
||||||
|
append(green.hexConverter())
|
||||||
|
append(blue.hexConverter())
|
||||||
|
if (includeAlpha) {
|
||||||
|
append(alpha.hexConverter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Float.decimalToHex(): String =
|
||||||
|
roundToInt().toString(16).padStart(2, ' ')
|
||||||
|
|
||||||
|
fun Float.percentageToHex(): String =
|
||||||
|
times(255).roundToInt().toString(16).padStart(2, ' ')
|
||||||
|
|
||||||
|
fun PlayerData.latLng(): LatLng = Maps.L.latLng((position.y * -1) to position.x)
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
package dev.adamko.kafkatorio.webmap
|
||||||
|
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
|
val jsonMapper = Json {
|
||||||
|
prettyPrint = true
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package dev.adamko.kafkatorio.webmap
|
||||||
|
|
||||||
|
import externals.leaflet.geo.CRS
|
||||||
|
import externals.leaflet.geo.LatLng
|
||||||
|
import io.kvision.maps.DefaultTileLayers
|
||||||
|
import io.kvision.maps.Maps
|
||||||
|
import io.kvision.utils.px
|
||||||
|
|
||||||
|
//
|
||||||
|
//val polyline = Maps.L.polyline(
|
||||||
|
// listOf(
|
||||||
|
// LatLng(55, 2),
|
||||||
|
// LatLng(65, 2),
|
||||||
|
// LatLng(65, 20),
|
||||||
|
// LatLng(55, 20),
|
||||||
|
// LatLng(55, 2),
|
||||||
|
// )
|
||||||
|
//) {
|
||||||
|
// noClip = true
|
||||||
|
//}
|
||||||
|
|
||||||
|
fun createFactorioMap() = Maps {
|
||||||
|
width = 800.px
|
||||||
|
height = 800.px
|
||||||
|
margin = 10.px
|
||||||
|
|
||||||
|
configureLeafletMap {
|
||||||
|
setView(LatLng(0, 0), 13)
|
||||||
|
|
||||||
|
// DefaultTileLayers.OpenStreetMap.addTo(this)
|
||||||
|
|
||||||
|
with(options) {
|
||||||
|
crs = CRS.Simple
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
package dev.adamko.kafkatorio.webmap
|
||||||
|
|
||||||
|
import dev.adamko.kafkatorio.events.schema.FactorioEvent
|
||||||
|
import dev.adamko.kafkatorio.events.schema.PlayerData
|
||||||
|
import externals.leaflet.geo.LatLng
|
||||||
|
import externals.leaflet.layer.overlay.Tooltip
|
||||||
|
import externals.leaflet.layer.vector.CircleMarker
|
||||||
|
import io.kvision.maps.Maps
|
||||||
|
import io.kvision.maps.Maps.Companion.L
|
||||||
|
import io.kvision.redux.ReduxStore
|
||||||
|
import io.kvision.redux.createReduxStore
|
||||||
|
import io.kvision.utils.obj
|
||||||
|
import redux.RAction
|
||||||
|
|
||||||
|
fun createFactorioReduxStore(): ReduxStore<FactorioGameState, FactorioUpdate> =
|
||||||
|
createReduxStore(
|
||||||
|
::factorioGameReducer,
|
||||||
|
FactorioGameState(
|
||||||
|
kvMaps = createFactorioMap(),
|
||||||
|
players = emptyMap()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
data class FactorioGameState(
|
||||||
|
val kvMaps: Maps,
|
||||||
|
val players: Map<String, PlayerState>,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
sealed class FactorioUpdate : RAction {
|
||||||
|
data class PlayerUpdate(val event: FactorioEvent<*>, val playerData: PlayerData) :
|
||||||
|
FactorioUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun factorioGameReducer(state: FactorioGameState, update: FactorioUpdate): FactorioGameState =
|
||||||
|
when (update) {
|
||||||
|
is FactorioUpdate.PlayerUpdate -> {
|
||||||
|
|
||||||
|
val playerState = state.players.getOrElse(update.playerData.name) {
|
||||||
|
val newState = PlayerState(update.playerData)
|
||||||
|
state.kvMaps.leafletMap {
|
||||||
|
addLayer(newState.mapMarker)
|
||||||
|
newState.mapMarker.openPopup()
|
||||||
|
// setView(update.playerData.latLng())
|
||||||
|
}
|
||||||
|
newState
|
||||||
|
}
|
||||||
|
|
||||||
|
playerState.update(update.playerData)
|
||||||
|
|
||||||
|
val updatedPlayersState = state.players + (update.playerData.name to playerState)
|
||||||
|
state.copy(players = updatedPlayersState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
data class PlayerState(
|
||||||
|
private var playerData: PlayerData,
|
||||||
|
val mapMarker: CircleMarker = createMapMarker(playerData)
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun update(playerData: PlayerData) {
|
||||||
|
this.playerData = playerData
|
||||||
|
mapMarker.setLatLng(playerData.latLng())
|
||||||
|
println("updated player ${playerData.name}")
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun createMapMarker(playerData: PlayerData): CircleMarker {
|
||||||
|
|
||||||
|
val playerLatLng = playerData.latLng()
|
||||||
|
val playerMapTooltip = "${playerData.name} [$playerLatLng]"
|
||||||
|
|
||||||
|
val circle = L.circleMarker(playerLatLng) {
|
||||||
|
color = playerData.colour.toHexString(false)
|
||||||
|
fillColor = color
|
||||||
|
fillOpacity = 1f
|
||||||
|
radius = 10
|
||||||
|
className = playerData.objectName
|
||||||
|
// interactive = false
|
||||||
|
}
|
||||||
|
|
||||||
|
circle.bindTooltip(playerMapTooltip, obj<Tooltip.TooltipOptions> {
|
||||||
|
// interactive = false
|
||||||
|
})
|
||||||
|
|
||||||
|
return circle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package dev.adamko.kafkatorio.webmap
|
||||||
|
|
||||||
|
import dev.adamko.kafkatorio.events.schema.FactorioEvent
|
||||||
|
import dev.adamko.kafkatorio.events.schema.FactorioObjectData
|
||||||
|
import dev.adamko.kafkatorio.events.schema.PlayerData
|
||||||
|
import io.kvision.redux.ReduxStore
|
||||||
|
import kotlinx.serialization.decodeFromString
|
||||||
|
import org.w3c.dom.MessageEvent
|
||||||
|
import org.w3c.dom.WebSocket
|
||||||
|
|
||||||
|
class WebsocketService(
|
||||||
|
private val wsUrl: String,
|
||||||
|
private val reduxStore: ReduxStore<FactorioGameState, FactorioUpdate>,
|
||||||
|
) {
|
||||||
|
private val ws = WebSocket(wsUrl)
|
||||||
|
|
||||||
|
init {
|
||||||
|
ws.onmessage = ::handleMessageEvent
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleMessageEvent(msg: MessageEvent) {
|
||||||
|
|
||||||
|
val data = msg.data as? String
|
||||||
|
|
||||||
|
if (
|
||||||
|
data != null
|
||||||
|
&& data.trim().startsWith("{")
|
||||||
|
&& data.trim().endsWith("}")
|
||||||
|
) {
|
||||||
|
|
||||||
|
println(data.replace('\n', ' '))
|
||||||
|
val event: FactorioEvent<FactorioObjectData> = jsonMapper.decodeFromString(data)
|
||||||
|
|
||||||
|
when (val eventData = event.data) {
|
||||||
|
is PlayerData -> {
|
||||||
|
reduxStore.dispatch(FactorioUpdate.PlayerUpdate(event, eventData))
|
||||||
|
}
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println(data)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>KVision Template</title>
|
<title>Kafkatorio Web Map</title>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootswatch@5.1.0/dist/superhero/bootstrap.min.css" integrity="sha256-T8h7oW5tHp4MhFhmRoDI8xjnB2ld89qSgc3s9g8T0uU=" crossorigin="anonymous">
|
||||||
<script type="text/javascript" src="main.bundle.js"></script>
|
<script type="text/javascript" src="main.bundle.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -21,3 +21,14 @@ enableFeaturePreview("VERSION_CATALOGS")
|
||||||
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
||||||
|
|
||||||
apply(from = "./buildSrc/repositories.settings.gradle.kts")
|
apply(from = "./buildSrc/repositories.settings.gradle.kts")
|
||||||
|
|
||||||
|
@Suppress("UnstableApiUsage") // centralized repositories is incubating
|
||||||
|
dependencyResolutionManagement {
|
||||||
|
repositories {
|
||||||
|
mavenLocal {
|
||||||
|
content {
|
||||||
|
includeGroup("io.kvision")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue