Skip to content

Commit c56b3de

Browse files
committed
working :3
1 parent 3b43ed3 commit c56b3de

32 files changed

+301
-61
lines changed

src/main/kotlin/com/lambda/command/commands/BuildCommand.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import com.lambda.brigadier.argument.value
2525
import com.lambda.brigadier.executeWithResult
2626
import com.lambda.brigadier.required
2727
import com.lambda.command.LambdaCommand
28-
import com.lambda.context.AutomationConfig
28+
import com.lambda.config.AutomationConfig
2929
import com.lambda.interaction.construction.StructureRegistry
3030
import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure
3131
import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint

src/main/kotlin/com/lambda/command/commands/ModuleCommand.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import com.lambda.threading.runSafe
3232
import com.lambda.util.Communication.info
3333
import com.lambda.util.Communication.joinToText
3434
import com.lambda.util.Communication.warn
35-
import com.lambda.util.StringUtils
3635
import com.lambda.util.StringUtils.findSimilarStrings
3736
import com.lambda.util.extension.CommandBuilder
3837
import com.lambda.util.text.ClickEvents.suggestCommand
@@ -76,7 +75,7 @@ object ModuleCommand : LambdaCommand(
7675

7776
required(string("module name")) { moduleName ->
7877
suggests { _, builder ->
79-
ModuleRegistry.moduleNames.forEach {
78+
ModuleRegistry.moduleNameMap.keys.forEach {
8079
builder.suggest(it)
8180
}
8281
builder.buildFuture()
@@ -95,7 +94,7 @@ object ModuleCommand : LambdaCommand(
9594
literal("not found!")
9695
}
9796
val similarModules = name.findSimilarStrings(
98-
ModuleRegistry.moduleNames,
97+
ModuleRegistry.moduleNameMap.keys,
9998
3
10099
)
101100
if (similarModules.isEmpty()) return@buildText

src/main/kotlin/com/lambda/command/commands/TransferCommand.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import com.lambda.brigadier.argument.value
2727
import com.lambda.brigadier.executeWithResult
2828
import com.lambda.brigadier.required
2929
import com.lambda.command.LambdaCommand
30-
import com.lambda.context.AutomationConfig
30+
import com.lambda.config.AutomationConfig
3131
import com.lambda.interaction.material.StackSelection.Companion.selectStack
3232
import com.lambda.interaction.material.container.ContainerManager
3333
import com.lambda.interaction.material.container.ContainerManager.containerWithMaterial

src/main/kotlin/com/lambda/context/AutomationConfig.kt renamed to src/main/kotlin/com/lambda/config/AutomationConfig.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@
1515
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

18-
package com.lambda.context
18+
package com.lambda.config
1919

20-
import com.lambda.config.AbstractSetting
21-
import com.lambda.config.Configurable
2220
import com.lambda.config.configurations.AutomationConfigs
2321
import com.lambda.config.groups.BreakSettings
2422
import com.lambda.config.groups.BuildSettings
@@ -28,6 +26,7 @@ import com.lambda.config.groups.InteractSettings
2826
import com.lambda.config.groups.InventorySettings
2927
import com.lambda.config.groups.PlaceSettings
3028
import com.lambda.config.groups.RotationSettings
29+
import com.lambda.context.Automated
3130
import com.lambda.event.events.onStaticRender
3231
import com.lambda.interaction.construction.result.Drawable
3332
import com.lambda.module.Module
@@ -37,8 +36,9 @@ import kotlin.reflect.jvm.isAccessible
3736

3837
@Suppress("unchecked_cast", "unused")
3938
open class AutomationConfig(
40-
override val name: String
41-
) : Configurable(AutomationConfigs), Automated {
39+
override val name: String,
40+
configuration: Configuration = AutomationConfigs
41+
) : Configurable(configuration), Automated {
4242
enum class Group(override val displayName: String) : NamedEnum {
4343
Build("Build"),
4444
Break("Break"),
@@ -65,12 +65,12 @@ open class AutomationConfig(
6565
companion object {
6666
context(module: Module)
6767
fun automationConfig(name: String = module.name, edits: (AutomationConfig.() -> Unit)? = null): AutomationConfig =
68-
AutomationConfig(name).apply { edits?.invoke(this) }
68+
AutomationConfig("$name Automation Config").apply { edits?.invoke(this) }
6969

7070
fun automationConfig(name: String, edits: (AutomationConfig.() -> Unit)? = null): AutomationConfig =
71-
AutomationConfig(name).apply { edits?.invoke(this) }
71+
AutomationConfig("$name Automation Config").apply { edits?.invoke(this) }
7272

73-
object DEFAULT : AutomationConfig("Default") {
73+
object DEFAULT : AutomationConfig("Default Automation Config") {
7474
val renders by setting("Render", false).group(Group.Render)
7575
val avoidDesync by setting("Avoid Desync", true, "Cancels incoming inventory update packets if they match previous actions").group(Group.Debug)
7676
val desyncTimeout by setting("Desync Timeout", 30, 1..30, 1, unit = " ticks", description = "Time to store previous inventory actions before dropping the cache") { avoidDesync }.group(Group.Debug)

src/main/kotlin/com/lambda/config/Configuration.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import com.lambda.Lambda.LOG
2626
import com.lambda.Lambda.gson
2727
import com.lambda.config.Configuration.Companion.configurables
2828
import com.lambda.config.configurations.ModuleConfigs
29+
import com.lambda.core.Loadable
2930
import com.lambda.event.events.ClientEvent
3031
import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe
3132
import com.lambda.threading.runIO
@@ -54,18 +55,19 @@ import kotlin.time.Duration.Companion.minutes
5455
* @property primary The primary file where the configuration is saved.
5556
* @property configurables A set of [Configurable] objects that this configuration manages.
5657
*/
57-
abstract class Configuration : Jsonable {
58+
abstract class Configuration : Jsonable, Loadable {
59+
override val priority = 1
5860
abstract val configName: String
5961
abstract val primary: File
6062

6163
val configurables = mutableSetOf<Configurable>()
6264
private val backup: File
6365
get() = File("${primary.parent}/${primary.nameWithoutExtension}-backup.${primary.extension}")
6466

65-
init {
67+
override fun load(): String {
6668
listenUnsafe<ClientEvent.Shutdown>(Int.MIN_VALUE) { trySave() }
67-
6869
register()
70+
return super.load()
6971
}
7072

7173
// Avoid context-leaking warning
@@ -95,7 +97,7 @@ abstract class Configuration : Jsonable {
9597
}
9698
}
9799

98-
fun save() = runCatching {
100+
private fun save() = runCatching {
99101
primary.createIfNotExists()
100102
.let {
101103
it.writeText(gson.toJson(toJson()))
@@ -107,12 +109,12 @@ abstract class Configuration : Jsonable {
107109
* Loads the config from the [file]
108110
* Encapsulates [JsonIOException] and [JsonSyntaxException] in a runCatching block
109111
*/
110-
fun load(file: File) = runCatching {
112+
private fun load(file: File) = runCatching {
111113
file.ifNotExists { LOG.warn("No configuration file found for ${configName.capitalize()}. Creating new file when saving.") }
112114
.ifExists { loadFromJson(JsonParser.parseReader(it.reader()).asJsonObject) }
113115
}
114116

115-
fun tryLoad() = runIO {
117+
open fun tryLoad() = runIO {
116118
load(primary)
117119
.onSuccess {
118120
val message = "${configName.capitalize()} config loaded."
@@ -135,7 +137,7 @@ abstract class Configuration : Jsonable {
135137
}
136138
}
137139

138-
fun trySave(logToChat: Boolean = false) = runIO {
140+
open fun trySave(logToChat: Boolean = false) = runIO {
139141
save()
140142
.onSuccess {
141143
val message = "Saved ${configName.capitalize()} config."
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.config
19+
20+
import kotlinx.coroutines.Job
21+
22+
abstract class DynamicConfiguration : Configuration() {
23+
private val preLoadListeners = mutableListOf<() -> Unit>()
24+
private val postLoadListeners = mutableListOf<() -> Unit>()
25+
private val preSaveListeners = mutableListOf<() -> Unit>()
26+
private val postSaveListeners = mutableListOf<() -> Unit>()
27+
28+
override fun tryLoad(): Job {
29+
preLoadListeners.forEach { it() }
30+
return super.tryLoad().also { job ->
31+
job.invokeOnCompletion { postLoadListeners.forEach { it() } }
32+
}
33+
}
34+
35+
override fun trySave(logToChat: Boolean): Job {
36+
preSaveListeners.forEach { it() }
37+
return super.trySave(logToChat).also { job ->
38+
job.invokeOnCompletion { postSaveListeners.forEach { it() } }
39+
}
40+
}
41+
42+
fun onPreLoad(block: () -> Unit) {
43+
preLoadListeners.add(block)
44+
}
45+
46+
fun onPostLoad(block: () -> Unit) {
47+
postLoadListeners.add(block)
48+
}
49+
50+
fun onPreSave(block: () -> Unit) {
51+
preSaveListeners.add(block)
52+
}
53+
54+
fun onPostSave(block: () -> Unit) {
55+
postSaveListeners.add(block)
56+
}
57+
}

src/main/kotlin/com/lambda/context/MutableAutomationConfig.kt renamed to src/main/kotlin/com/lambda/config/MutableAutomationConfig.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@
1515
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

18-
package com.lambda.context
18+
package com.lambda.config
1919

2020
import com.lambda.config.groups.BuildConfig
2121
import com.lambda.config.groups.EatConfig
22+
import com.lambda.context.Automated
2223
import com.lambda.interaction.request.breaking.BreakConfig
2324
import com.lambda.interaction.request.hotbar.HotbarConfig
2425
import com.lambda.interaction.request.interacting.InteractConfig
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.config
19+
20+
import com.lambda.config.configurations.UserAutomationConfigs
21+
import com.lambda.module.ModuleRegistry.moduleNameMap
22+
23+
class UserAutomationConfig(override val name: String) : AutomationConfig(name, UserAutomationConfigs) {
24+
val linkedModules = setting("Linked Modules", moduleNameMap.filter { it.value.defaultAutomationConfig != Companion.DEFAULT }.keys, emptySet())
25+
.onSelect { module -> moduleNameMap[module]?.automationConfig = this@UserAutomationConfig }
26+
.onDeselect { module ->
27+
moduleNameMap[module]?.let { module ->
28+
module.automationConfig = module.defaultAutomationConfig
29+
}
30+
}
31+
}

src/main/kotlin/com/lambda/config/configurations/ConfigLoader.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.lambda.config.Configuration
2121
import com.lambda.core.Loadable
2222

2323
object ConfigLoader: Loadable {
24+
override val priority = 0
2425
override fun load(): String {
2526
Configuration.configurations.forEach {
2627
it.tryLoad()
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.config.configurations
19+
20+
import com.google.gson.JsonParser
21+
import com.lambda.config.DynamicConfiguration
22+
import com.lambda.config.UserAutomationConfig
23+
import com.lambda.module.ModuleRegistry.moduleNameMap
24+
import com.lambda.util.FileUtils.ifExists
25+
import com.lambda.util.FolderRegister
26+
import java.io.File
27+
28+
object UserAutomationConfigs : DynamicConfiguration() {
29+
override val configName = "custom-automation"
30+
override val primary: File = FolderRegister.config.resolve("${configName}.json").toFile()
31+
32+
override fun load(): String {
33+
onPreLoad {
34+
primary.ifExists {
35+
JsonParser.parseReader(it.reader()).asJsonObject.entrySet().forEach { (name, _) ->
36+
if (configurables.any { config -> config.name == name }) return@forEach
37+
UserAutomationConfig(name)
38+
}
39+
}
40+
}
41+
42+
onPostLoad {
43+
configurables.forEach {
44+
val config = it as? UserAutomationConfig ?: throw IllegalStateException("UserAutomationConfigs contains non-AutomationConfig")
45+
config.linkedModules.value.forEach { moduleName ->
46+
moduleNameMap[moduleName]?.automationConfig = config
47+
}
48+
}
49+
}
50+
51+
return super.load()
52+
}
53+
}

0 commit comments

Comments
 (0)