ConfigTracker

Tracks the marketplace config the client runs.

A loaded config is State.TRACKED while the settings match what was loaded and State.EDITING once they differ. The settings from before the first load are kept as a backup until the user restores or detaches.

A config's config dependencies are applied before it, depth-first in their order, and its add-on and script dependencies are installed. The settings after the dependencies are its base: an overlay only publishes what differs from it.

Loading a local config over it stops tracking, unless the local config was saved from it; see loadedLocal.

Types

Link copied to clipboard
data class LoadResult(val installed: List<MarketplaceItem>, val restartRequired: Boolean, val unavailable: List<Unavailable>)

Dependencies load installed; restartRequired when one only works after a restart. unavailable are the ones left out since they or what they need do not load with this game.

Link copied to clipboard
Link copied to clipboard
data class Step(val itemId: Int, val revisionId: Int)

Properties

Link copied to clipboard

author/name of the tracked config, or its name while the author is unknown.

Link copied to clipboard
Link copied to clipboard

Stores the ValueGroup in which the ValueGroup is included, can be null.

Link copied to clipboard
open val baseKey: String

The base key used when base is null, otherwise the baseKey from base is used when its base is null and so on.

Link copied to clipboard

Config dependencies applied before the tracked config, in order.

Link copied to clipboard
@get:JvmName(name = "getContainedValues")
val containedValues: Array<Value<*>>
Link copied to clipboard
open override val debugDisplayName: FormattedCharSequence
Link copied to clipboard
open override val debugOwnerId: String
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

If true, value will not be included in generated public config. Can be set using doNotIncludeWhen or doNotIncludeAlways.

Link copied to clipboard
val EventListener.eventListenerScope: CoroutineScope

Get the related CoroutineScope of receiver EventListener.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

Group for optional inclusion during configuration saving. Managed by AutoConfig.

Link copied to clipboard
Link copied to clipboard

If true, value will always keep inner equals defaultValue.

Link copied to clipboard

If false, the value is neither written to nor read from config files, but still reaches the GUI. For values whose state lives elsewhere, such as another client's modules.

Link copied to clipboard
Link copied to clipboard
var itemId: Int
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

We write to this temp file, we can safely rename jsonTmpFile to jsonFile, to eliminate any chances of data loss.

Link copied to clipboard
var key: String?
Link copied to clipboard

The local config that last replaced the settings, until a marketplace config does.

Link copied to clipboard
@SerializedName(value = "name")
val name: String
Link copied to clipboard

If true, value will not be included in generated RestAPI config.

Link copied to clipboard
Link copied to clipboard
open val running: Boolean

Returns whether the listenable is running or not, this is based on the parent listenable and if no parent is present, it will return the opposite of isDestructed.

Link copied to clipboard
Link copied to clipboard

Id of the tracked config, which a local config saved now keeps as its origin.

Link copied to clipboard
Link copied to clipboard

Hides the value from the GUI while false. Configs keep it either way.

Functions

Link copied to clipboard
open fun after(ticks: Int, task: Runnable): AutoCloseable

Runs task once, ticks game ticks from now, unless this listener stops running first.

Link copied to clipboard
fun asStateFlow(): StateFlow<MutableCollection<Value<*>>>
Link copied to clipboard
fun bind(name: String, default: Int = InputConstants.UNKNOWN.value): BindValue
fun bind(name: String, default: InputBind): BindValue
Link copied to clipboard

Binds to the given input name.

fun Value<InputBind>.bind(key: InputConstants.Key, action: InputBind.BindAction, modifiers: Set<InputBind.Modifier>)

Binds to the given input type and code.

Link copied to clipboard
fun block(name: String, default: Block): Value<Block>
Link copied to clipboard
fun <C : SequencedSet<Block>> blocks(name: String, default: C): RegistryListValue<C, Block>
Link copied to clipboard
@JvmName(name = "bool")
fun boolean(name: String, default: Boolean, aliases: List<String> = emptyList()): Value<Boolean>
Link copied to clipboard
fun <C : SequencedSet<Identifier>> c2sPackets(name: String, default: C): RegistryListValue<C, Identifier>
Link copied to clipboard

Checks if this value should be included in the public configuration based on its doNotInclude condition and inclusionGroup.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
fun color(name: String, default: Color4b): Value<Color4b>
Link copied to clipboard
inline fun <E : Event, V> EventListener.computedOn(initialValue: V, priority: Short = 0, crossinline accumulator: (event: E, prev: V) -> V): ReadWriteProperty<EventListener, V>

Returns computed ReadWriteProperty based on the accumulator of specific event.

Link copied to clipboard
suspend fun create(session: OAuthSession, name: String, description: String, details: MarketplaceApi.ItemDetails): MarketplaceItem

Publishes the current settings as a new config and tracks it.

Link copied to clipboard
open override fun <T : Event> EventListener.createEventHook(eventClass: Class<T>, wrappedContext: CoroutineContext, priority: Short, handler: SuspendableEventHandler<T>): EventHook<T>
open override fun <T : Event> EventListener.createEventHook(eventClass: Class<T>, wrappedContext: CoroutineContext, priority: Short, handler: SuspendableEventHandler<T>): EventHook<T>
Link copied to clipboard
inline fun curve(name: String, block: CurveValue.Builder.() -> Unit): CurveValue
fun curve(name: String, default: MutableList<Vector2f>, xAxis: CurveValue.Axis, yAxis: CurveValue.Axis, tension: Float = CurveValue.DEFAULT_TENSION): CurveValue
Link copied to clipboard
inline fun DebuggedOwner.debugGeometry(name: String, lazyGeometry: () -> ModuleDebug.DebuggedGeometry?)
Link copied to clipboard
inline fun DebuggedOwner.debugParameter(name: String, lazyValue: () -> Any?)
Link copied to clipboard
suspend fun delete(session: OAuthSession)
Link copied to clipboard
open fun deserializeFrom(gson: Gson, element: JsonElement)

Deserialize value from JSON

Link copied to clipboard
suspend fun detach()

Keeps the current settings and stops tracking.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
fun <T : ValueGroup> drop(valueGroup: T): T
Link copied to clipboard
fun easing(name: String, default: Easing): ChoiceListValue<Easing>
Link copied to clipboard
fun <C : SequencedSet<Identifier>> enchantments(name: String, default: C): RegistryListValue<C, Identifier>
Link copied to clipboard
@JvmName(name = "create")
fun <T : Entity> EventListener.EntityLookup(collector: EntityLookup.Collector<T>): EntityLookup<T>
Link copied to clipboard
fun <C : SequencedSet<EntityType<*>>> entityTypes(name: String, default: C): RegistryListValue<C, EntityType<*>>
Link copied to clipboard
fun <T : Enum<T>, Tagged> enumChoice(name: String, default: T): ChoiceListValue<T>

For Java, which cannot call the reified overload.

inline fun <T : Enum<T>, Tagged> enumChoice(name: String, default: T, aliases: List<String> = emptyList()): ChoiceListValue<T>
fun <T : Tagged> enumChoice(name: String, default: T, choices: Set<T>, aliases: List<String> = emptyList()): ChoiceListValue<T>
Link copied to clipboard
open fun every(ticks: Int, task: Runnable): AutoCloseable

Runs task every ticks game ticks while this listener is running, the first time after ticks.

Link copied to clipboard
Link copied to clipboard
fun file(name: String, default: File? = null, dialogMode: FileDialogMode = FileDialogMode.OPEN_FILE, supportedExtensions: Set<String>? = null): FileValue
Link copied to clipboard
@JvmName(name = "floating")
fun float(name: String, default: Float, min: Float, max: Float, suffix: String = ""): RangedValue<Float>
@JvmName(name = "floating")
fun float(name: String, default: Float, range: ClosedFloatingPointRange<Float>, suffix: String = "", aliases: List<String> = emptyList()): RangedValue<Float>
Link copied to clipboard
Link copied to clipboard
suspend fun fork(session: OAuthSession, name: String, description: String, visibility: MarketplaceItemVisibility): MarketplaceItem

Publishes the edited settings as a new config that links back to the tracked revision.

Link copied to clipboard
Link copied to clipboard
@JvmName(name = "getTagValue")
fun getTagValue(): Any
Link copied to clipboard
@JvmName(name = "getValue")
fun getValue(): Any

operator fun getValue(u: Any?, property: KProperty<*>): MutableCollection<Value<*>>

Support for delegated properties example: var autoaim by boolean(name = "autoaim", default = true) if(!autoaim) autoaim = true

Link copied to clipboard
inline fun <T : Event> EventListener.handler(priority: Short = 0, handler: Consumer<T>): EventHook<T>
fun <T : Event> EventListener.handler(eventClass: Class<T>, priority: Short = 0, handler: Consumer<T>): EventHook<T>
Link copied to clipboard
Link copied to clipboard
open override fun inclusionGroup(group: OptionalInclusion): ValueGroup
Link copied to clipboard
@JvmName(name = "integer")
fun int(name: String, default: Int, min: Int, max: Int, suffix: String = ""): RangedValue<Int>
@JvmName(name = "integer")
fun int(name: String, default: Int, range: IntRange, suffix: String = "", aliases: List<String> = emptyList()): RangedValue<Int>
Link copied to clipboard
fun intRange(name: String, default: IntRange, range: IntRange, suffix: String = "", aliases: List<String> = emptyList()): RangedValue<IntRange>
Link copied to clipboard
fun item(name: String, default: Item): Value<Item>
Link copied to clipboard
fun <C : MutableList<Item>> itemList(name: String, default: C): RegistryMutableListValue<C, Item>
inline fun <T : MutableSet<E>, E> itemList(name: String, defaultValue: T, items: Set<ItemListValue.NamedItem<E>>, valueType: ValueType): ItemListValue<T, E>
fun <T : MutableSet<E>, E> itemList(name: String, defaultValue: T, items: Set<ItemListValue.NamedItem<E>>, valueType: ValueType, innerType: Class<E>): ItemListValue<T, E>
Link copied to clipboard
fun <C : SequencedSet<Item>> items(name: String, default: C): RegistryListValue<C, Item>
Link copied to clipboard
fun ValueGroup.json(valueObject: JsonObject)

Assigns the value of the settings to the component

Link copied to clipboard
fun key(name: String, default: InputConstants.Key = InputConstants.UNKNOWN): Value<InputConstants.Key>
fun key(name: String, default: Int): Value<InputConstants.Key>
Link copied to clipboard
inline fun <T : MutableCollection<E>, E> list(name: String, defaultValue: T, valueType: ValueType): ListValue<T, E>
fun <T : MutableCollection<E>, E> list(name: String, defaultValue: T, valueType: ValueType, innerType: Class<E>): ListValue<T, E>
Link copied to clipboard

Uses text instead of a translation key, for descriptions that come from outside LiquidBounce.

Link copied to clipboard
suspend fun load(item: MarketplaceItem, revisionId: Int, modules: Collection<ValueGroup> = emptyList()): ConfigTracker.LoadResult

Applies revisionId of item after its config dependencies and installs its add-on and script dependencies. A full load starts tracking it, a load restricted to modules only applies that slice of every step.

Link copied to clipboard
fun loadedLocal(name: String, origin: Int?, partial: Boolean): String?

Settings of the local config name were applied, only some modules of it when partial. A partial load, or one of a config saved from the tracked one (origin is its trackedItemId), goes on as edits of the tracked config. Any other replaces it: tracking stops, the backup stays.

Link copied to clipboard
suspend fun loadExternal(source: String, modules: Collection<ValueGroup> = emptyList())

Applies a config that does not come from the marketplace. It stops tracking but keeps the backup.

Link copied to clipboard

Re-reads the file, dropping unsaved changes.

Link copied to clipboard
fun <T : Any, R> Value<T>.mapReadOnly(transform: (T) -> R): ReadOnlyProperty<Any?, R>
Link copied to clipboard
fun <C : SequencedSet<MobEffect>> mobEffects(name: String, default: C): RegistryListValue<C, MobEffect>
Link copied to clipboard
fun <T : Mode> modes(eventListener: EventListener?, name: String, activeCallback: ToIntFunction<List<T>>, modesCallback: (ModeValueGroup<T>) -> Array<T>): ModeValueGroup<T>
Link copied to clipboard
inline fun <T : Enum<T>, Tagged> multiEnumChoice(name: String, default: Iterable<T>, canBeNone: Boolean = true): MultiChoiceListValue<T?>
inline fun <T : Enum<T>, Tagged> multiEnumChoice(name: String, vararg default: T, canBeNone: Boolean = true): MultiChoiceListValue<T?>
inline fun <T : Enum<T>, Tagged> multiEnumChoice(name: String, default: EnumSet<T> = enumSetOf(), choices: EnumSet<T> = enumSetAllOf(), canBeNone: Boolean = true): MultiChoiceListValue<T?>
inline fun <T : Enum<T>, Tagged> multiEnumChoice(name: String, default: SequencedSet<T>, choices: EnumSet<T> = enumSetAllOf(), canBeNone: Boolean = true): MultiChoiceListValue<T?>
fun <T : Tagged> multiEnumChoice(name: String, default: MutableSet<T>, choices: Set<T>, canBeNone: Boolean, isOrderSensitive: Boolean): MultiChoiceListValue<T>

fun <T : Enum<T>, Tagged> multiEnumChoice(name: String, type: Class<T>, default: Collection<T>, canBeNone: Boolean = true): MultiChoiceListValue<T>

For Java, which cannot call the reified overloads.

Link copied to clipboard
inline fun <T : MutableCollection<E>, E> mutableList(name: String, defaultValue: T, valueType: ValueType): MutableListValue<T, E>
fun <T : MutableCollection<E>, E> mutableList(name: String, defaultValue: T, valueType: ValueType, innerType: Class<E>): MutableListValue<T, E>
Link copied to clipboard
inline fun <E : Event> EventListener.newEventHook(priority: Short = 0, handler: Consumer<E>): EventHook<E>
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
open fun <E : Event> on(type: Class<E>, handler: Consumer<E>): AutoCloseable

open fun <E : Event> on(type: Class<E>, priority: Short, handler: Consumer<E>): AutoCloseable

Calls handler for every type event while this listener is running. Higher priority runs first. Close the result to stop early; unregister does the same for all of them.

Link copied to clipboard
inline fun <T : Event> EventListener.once(priority: Short = 0, crossinline handler: (T) -> Unit): EventHook<T>
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
open fun onTick(task: Runnable): AutoCloseable

task every game tick while this listener is running.

Link copied to clipboard
suspend fun overlay(session: OAuthSession, name: String, description: String, visibility: MarketplaceItemVisibility): MarketplaceItem

Publishes only what was changed on top of the tracked config, as a new config that depends on it, and tracks that.

Link copied to clipboard
Link copied to clipboard
fun ValueGroup.percentageChance(name: String, default: Float, range: ClosedFloatingPointRange<Float> = 0f..100f, randomGetter: Supplier<out RandomGenerator> = DEFAULT_RANDOM): PercentageChance<Float>
fun ValueGroup.percentageChance(name: String, default: Int, range: IntRange = 0..100, randomGetter: Supplier<out RandomGenerator> = DEFAULT_RANDOM): PercentageChance<Int>
Link copied to clipboard
open fun prepareDeserialize(jsonObject: JsonObject)

Allows dynamic groups to create their children before stored values are applied.

Link copied to clipboard
fun regex(name: String, default: Regex): Value<Regex>
Link copied to clipboard
Link copied to clipboard
inline fun <T : SequencedSet<E>, E> registryList(name: String, defaultValue: T, valueType: ValueType): RegistryListValue<T, E>
fun <T : SequencedSet<E>, E> registryList(name: String, defaultValue: T, valueType: ValueType, innerType: Class<E>): RegistryListValue<T, E>
Link copied to clipboard
inline fun <T : MutableList<E>, E> registryMutableList(name: String, defaultValue: T, valueType: ValueType): RegistryMutableListValue<T, E>
fun <T : MutableList<E>, E> registryMutableList(name: String, defaultValue: T, valueType: ValueType, innerType: Class<E>): RegistryMutableListValue<T, E>
Link copied to clipboard

Remove cached scope and cancel it.

Link copied to clipboard
Link copied to clipboard
inline fun <T : Event> EventListener.repeated(times: Int = 1, priority: Short = 1, crossinline handler: (T) -> Unit): EventHook<T>
Link copied to clipboard
open override fun restore()

Restore all values to their default values

Link copied to clipboard
suspend fun restoreBackup()

Returns to the settings from before the first marketplace load.

Link copied to clipboard
suspend fun revert()

Re-applies the tracked revision and its config dependencies, dropping local edits.

Link copied to clipboard
fun <C : SequencedSet<Identifier>> s2cPackets(name: String, default: C): RegistryListValue<C, Identifier>
Link copied to clipboard

Writes the file now; the client does so on exit anyway.

Link copied to clipboard
inline fun <T : Event> EventListener.sequenceHandler(priority: Short = 0, dispatcher: CoroutineDispatcher? = null, onCancellation: Runnable? = null, crossinline eventHandler: SuspendableEventHandler<T>): EventHook<T>

Registers an event hook for events of type T and launches a sequence

Link copied to clipboard
Link copied to clipboard
open fun setByString(string: String)
Link copied to clipboard
operator fun setValue(u: Any?, property: KProperty<*>, t: MutableCollection<Value<*>>)
Link copied to clipboard
fun <C : SequencedSet<SoundEvent>> sounds(name: String, default: C): RegistryListValue<C, SoundEvent>
Link copied to clipboard
inline fun <T : Event> EventListener.suspendHandler(context: CoroutineContext = EmptyCoroutineContext, priority: Short = 0, behavior: SuspendHandlerBehavior = SuspendHandlerBehavior.Parallel.Default, noinline handler: SuspendableEventHandler<T>): EventHook<T>

Start a Job on event.

Link copied to clipboard
fun text(name: String, default: String): Value<String>
Link copied to clipboard
Link copied to clipboard
inline fun EventListener.tickHandler(dispatcher: CoroutineDispatcher? = null, onCancellation: Runnable? = null, crossinline eventHandler: suspend CoroutineScope.() -> Unit): EventHook<GameTickEvent>

Registers a repeatable sequence which repeats the execution of code on GameTickEvent.

Link copied to clipboard
open override fun toString(): String
Link copied to clipboard
fun <T : ValueGroup> tree(valueGroup: T): T
Link copied to clipboard
fun <T : ValueGroup> treeAll(vararg valueGroups: T)
Link copied to clipboard
Link copied to clipboard

Unbinds the key by setting it to UNKNOWN_KEY.

Link copied to clipboard
open fun unregister()

Unregisters the event handler from the manager. This decision is FINAL! After the class was unregistered we cannot restore the handlers.

Link copied to clipboard
inline fun <T : Event> EventListener.until(priority: Short = 0, crossinline handler: (T) -> Boolean): EventHook<T>
Link copied to clipboard
suspend fun update(session: OAuthSession, changelog: String?): MarketplaceItemRevision

Uploads the edited settings as the tracked config's newest revision. With config dependencies, only what differs from them.

Link copied to clipboard
fun <V : Value<*>> value(value: V): V
fun <T : Any> value(name: String, defaultValue: T, valueType: ValueType = ValueType.INVALID, aliases: List<String> = emptyList()): Value<T>
Link copied to clipboard
fun vec2f(name: String, default: Vector2fc): Value<Vector2fc>
Link copied to clipboard
fun vec3d(name: String, default: Vec3 = Vec3.ZERO, useLocateButton: Boolean = true, aliases: List<String> = emptyList()): Value<Vec3>
Link copied to clipboard
fun vec3i(name: String, default: Vec3i = Vec3i.ZERO, useLocateButton: Boolean = true, aliases: List<String> = emptyList()): Value<Vec3i>
Link copied to clipboard
Link copied to clipboard
inline suspend fun <T : Event> EventListener.waitMatches(priority: Short = 0, predicate: Predicate<T>): T

Wait an event of type T which matches given predicate.

suspend fun <T : Event> EventListener.waitMatches(eventClass: Class<T>, priority: Short, predicate: Predicate<T>): T
Link copied to clipboard
inline suspend fun <T : Event> EventListener.waitMatchesWithTimeout(timeout: Duration, priority: Short = 0, predicate: Predicate<T>): T?

Wait an event of type T which matches given predicate. If the timeout is exceeded, return null.

Link copied to clipboard
open fun walkInit()
Link copied to clipboard
fun walkKeyPath(previousBaseKey: String? = null)

Walks the path of the ValueGroup and its children

Link copied to clipboard

Wrap the original interceptor and make it auto-detect the listener's running state at suspension to determine whether to resume the continuation.