Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
8271992
Added ActivityManager and Activity abstract class
minecraft-simon Dec 13, 2022
7d2121e
More tests
Avanatiker Dec 13, 2022
ef2204c
First working activity system with example
Avanatiker Dec 14, 2022
b9e2377
Implemented HUD and InventoryTransactions
Avanatiker Dec 15, 2022
50c0b61
Generic info gather
Avanatiker Dec 15, 2022
3bd488f
Inventory stuff
Avanatiker Dec 15, 2022
3d1632d
PlaceBlockActivity and type tests
Avanatiker Dec 15, 2022
35d4786
Multi types using interfaces
Avanatiker Dec 16, 2022
bd0f1cf
Added render block interface
Avanatiker Dec 16, 2022
17b76a0
Added BreakBlockActivity and some sketches
Avanatiker Dec 16, 2022
91a0519
Extract item from container
Avanatiker Dec 17, 2022
273fbb9
Added CustomGoalActivity
Avanatiker Dec 18, 2022
4ab9dd2
Remove not working code
Avanatiker Dec 18, 2022
e11b6e5
Added Storage Management
Avanatiker Dec 18, 2022
a2d8172
Refactor names and small stuff
Avanatiker Dec 19, 2022
2d052a8
Owner property added
Avanatiker Dec 19, 2022
adae851
Move package
Avanatiker Dec 22, 2022
9187bf6
Test case for listener
Avanatiker Dec 22, 2022
50e3655
Fix for listening objects
Avanatiker Dec 22, 2022
d89a461
Added BreakDownEnderChests
Avanatiker Dec 22, 2022
af45ad5
Cleanup
Avanatiker Dec 22, 2022
edd346c
Rotation and timing optimizations
Avanatiker Dec 23, 2022
8ee5fcf
Remove unneeded activity
Avanatiker Dec 23, 2022
a4737ab
Sketch: Inventory 2.0
Avanatiker Dec 27, 2022
158d28d
Cleanup
Avanatiker Dec 28, 2022
3ad9a4f
First BuildBlockState test
Avanatiker Dec 28, 2022
41556d6
added some activities for auto-xp
minecraft-simon Dec 29, 2022
78551f9
General throwable usage
Avanatiker Dec 30, 2022
2b741fc
Iterative instant activity updates
Avanatiker Dec 30, 2022
9ede893
Added LoopingAmountActivity type
Avanatiker Dec 30, 2022
a31cd86
Added LoopingUntilActivity type and removed CompoundActivity
Avanatiker Dec 30, 2022
0f21fe7
Change example
Avanatiker Dec 30, 2022
4565b68
proposal for activity events
minecraft-simon Dec 30, 2022
f055da3
Use instead of SetState
Avanatiker Dec 30, 2022
32ec608
Fix stuff
Avanatiker Dec 30, 2022
335210f
Add anon option to hud
Avanatiker Dec 30, 2022
d0cf92f
Fix collecting drops
Avanatiker Dec 31, 2022
27acf3d
Exception system
Avanatiker Jan 2, 2023
b0130fa
Decision chains and exception improvement
Avanatiker Jan 2, 2023
2af0b94
Big refactor for exception handling
Avanatiker Jan 3, 2023
7d45057
Fix the InventoryManagerTwo sketch
Avanatiker Jan 3, 2023
4204948
Merge branch 'master' into activitySystem
Avanatiker Jan 8, 2023
5d421df
Macro and micro management
Avanatiker Jan 10, 2023
8071f8e
Module is now Activity
Avanatiker Jan 10, 2023
b24f52f
Formatting refactor
Avanatiker Jan 10, 2023
2d3ebb9
Not yet
Avanatiker Jan 10, 2023
63917a8
Fix PlaceBlock timeout
Avanatiker Jan 10, 2023
66ca9fe
Tweaks for structure building
Avanatiker Jan 10, 2023
f59e9a6
Bring back ignored blocks
Avanatiker Jan 10, 2023
5297ce5
Added working HighwayTools prototype
Avanatiker Jan 13, 2023
6b3fb44
Commands and cleanup
Avanatiker Jan 13, 2023
e871103
BuildBlock context system and rainbow highway
Avanatiker Jan 14, 2023
d1d5306
Stash dump
Avanatiker Jan 26, 2023
dd3fed0
Merge branch 'master' into activitySystem
Avanatiker Jan 26, 2023
1078fd9
Schematica API
rfresh2 Jan 26, 2023
970d864
Build schematic activity
rfresh2 Jan 28, 2023
7b1cc68
rename
rfresh2 Jan 28, 2023
96a1f4e
Support EnumFacing blocks, fixed item dump
Avanatiker Jan 30, 2023
3922386
Merge remote-tracking branch 'rfresh2/activitySystemWithSchematicaApi…
Avanatiker Jan 30, 2023
cb804f0
Add SchematicBuilder module
Avanatiker Jan 30, 2023
574cd07
Creative mode support and fixes
Avanatiker Jan 31, 2023
f7e3d5e
Added HalfBlock placements
Avanatiker Feb 2, 2023
664281c
Merge remote-tracking branch 'lambda-client/master' into activitySystem
Avanatiker Feb 2, 2023
4af30de
Fix block meta data and block rotations
Avanatiker Feb 2, 2023
e93a261
Add TrapDoors and Strairs support
Avanatiker Feb 2, 2023
be95fb3
Added Button support
Avanatiker Feb 2, 2023
0dba955
State properties rewrite and render fix
Avanatiker Feb 16, 2023
e932c2f
Merge branch 'master' into activitySystem
Avanatiker Feb 19, 2023
0f7f540
Better UP and BOTTOM place. Fix absent Schematica crash
Avanatiker Feb 19, 2023
985d263
Fix ItemBlockSpecials
Avanatiker Feb 20, 2023
013271c
Fix optimal stack calcultion
Avanatiker Feb 20, 2023
6bcd0c4
Place and Break rewrite and improved concurrent building
Avanatiker Feb 20, 2023
125eec6
Fix block replacement
Avanatiker Feb 20, 2023
a08ac55
Fix boxed tasks
Avanatiker Feb 20, 2023
11e9655
Adding concurrent build actions
Avanatiker Feb 22, 2023
b7156ac
Fix build order structure
Avanatiker Feb 24, 2023
1ba21dd
Revert to ConcurrentLinkedDeque and fancy break particles
Avanatiker Feb 26, 2023
c41ebe7
Best tool for mining
Avanatiker Feb 26, 2023
3058fac
Smol fixes
Avanatiker Feb 26, 2023
cd21bd0
Merge branch 'master' into activitySystem
Avanatiker Mar 3, 2023
2654c37
Thread sanitizing and other fixes
Avanatiker Mar 3, 2023
6454f09
Optimal tool selection and other optimizations
Avanatiker Mar 6, 2023
4e37373
Fix attempting activities and skipping ignore blocks
Avanatiker Mar 7, 2023
9c7a6ac
Lots of fixes
Avanatiker Mar 10, 2023
9fb4080
Clean up
Avanatiker Mar 12, 2023
e5dcf03
Multi module support
Avanatiker Mar 12, 2023
b098f1b
Merge branch 'master' into activitySystem
Avanatiker Mar 12, 2023
1a0a178
Fix build
Avanatiker Mar 12, 2023
ba54c29
Fix no autopathing
Avanatiker Mar 13, 2023
f8f18e9
Elevate path finding into BuildStructure
Avanatiker Mar 16, 2023
191f1e8
Rewrote priority system for BuildStructure
Avanatiker Mar 26, 2023
bad1b1a
Added overlay debug renderer and fix breaking bushes
Avanatiker Mar 27, 2023
c416617
Merge branch 'master' into activitySystem
Avanatiker Apr 7, 2023
ced80d8
Add render settings and graffiti module
Avanatiker May 5, 2023
7ccb883
Fix Graffiti logic
Avanatiker May 5, 2023
d74aa4c
Graffiti, StorageManagement, BlockPos setting and auto crafting
Avanatiker May 29, 2023
f2e012b
Quality of life settings for WorldEater
Avanatiker Jun 3, 2023
41c6918
Merge remote-tracking branch 'origin/master' into activitySystem
Avanatiker Jun 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,16 @@ dependencies {
implementation configurations.jarLibs
}

sourceSets {
schematica_api {
compileClasspath += main.compileClasspath
}

main {
compileClasspath += schematica_api.output
}
}

mixin {
defaultObfuscationEnv 'searge'
sourceSets {
Expand Down
355 changes: 355 additions & 0 deletions src/main/kotlin/com/lambda/client/activity/Activity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,355 @@
package com.lambda.client.activity

import com.lambda.client.activity.activities.construction.core.BuildStructure
import com.lambda.client.activity.types.AttemptActivity.Companion.checkAttempt
import com.lambda.client.activity.types.BuildActivity
import com.lambda.client.activity.types.DelayedActivity
import com.lambda.client.activity.types.DelayedActivity.Companion.checkDelayed
import com.lambda.client.activity.types.LoopWhileActivity.Companion.checkLoopingUntil
import com.lambda.client.activity.types.RenderAABBActivity
import com.lambda.client.activity.types.RenderAABBActivity.Companion.checkAABBRender
import com.lambda.client.activity.types.RepeatingActivity.Companion.checkRepeat
import com.lambda.client.activity.types.RotatingActivity.Companion.checkRotating
import com.lambda.client.activity.types.TimeoutActivity.Companion.checkTimeout
import com.lambda.client.event.LambdaEventBus
import com.lambda.client.event.ListenerManager
import com.lambda.client.event.SafeClientEvent
import com.lambda.client.gui.hudgui.elements.client.ActivityManagerHud
import com.lambda.client.manager.managers.ActivityManager
import com.lambda.client.manager.managers.ActivityManager.MAX_DEPTH
import com.lambda.client.module.AbstractModule
import com.lambda.client.util.BaritoneUtils
import com.lambda.client.util.color.ColorHolder
import com.lambda.client.util.graphics.font.TextComponent
import com.lambda.client.util.text.MessageSendHelper
import com.lambda.client.util.text.capitalize
import net.minecraft.entity.Entity
import net.minecraft.item.ItemBlock
import net.minecraft.util.math.AxisAlignedBB
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Vec3d
import org.apache.commons.lang3.time.DurationFormatUtils

abstract class Activity {
val subActivities = ArrayDeque<Activity>()
var status = Status.UNINITIALIZED
private var creationTime = 0L
var parent: Activity? = null
var owner: AbstractModule? = null
var depth = 0

open fun SafeClientEvent.onInitialize() {}

open fun SafeClientEvent.onChildInitialize(childActivity: Activity) {}

open fun SafeClientEvent.onSuccess() {}

open fun SafeClientEvent.onChildSuccess(childActivity: Activity) {}

/* Return true to catch the exception */
open fun SafeClientEvent.onFailure(exception: Exception): Boolean = false

open fun SafeClientEvent.onChildFailure(childActivities: ArrayDeque<Activity>, childException: Exception): Boolean = false

open fun SafeClientEvent.onCancel() {}

open fun addExtraInfo(
textComponent: TextComponent,
primaryColor: ColorHolder,
secondaryColor: ColorHolder
) {}

open fun getCurrentActivity(): Activity {
subActivities.firstOrNull()?.let {
with(it) {
return getCurrentActivity()
}
} ?: return this@Activity
}

val activityName get() = this.javaClass.simpleName ?: "Activity"

val age get() = if (creationTime != 0L) System.currentTimeMillis() - creationTime else 0L

val allSubActivities: List<Activity>
get() = run {
val activities = mutableListOf<Activity>()

parent?.let {
activities.add(this)
}

activities.addAll(subActivities.flatMap { it.allSubActivities })

activities
}

val hasNoSubActivities get() = subActivities.isEmpty()

fun SafeClientEvent.updateActivity() {
when (status) {
Status.UNINITIALIZED -> {
initialize()
}
Status.RUNNING -> {
if (!ListenerManager.listenerMap.containsKey(this@Activity)
&& hasNoSubActivities
&& this@Activity !is DelayedActivity
) success()
}
}
}

fun SafeClientEvent.updateTypesOnTick(activity: Activity) {
checkTimeout(activity)
checkDelayed(activity)
checkRotating(activity)
checkAABBRender()
}

fun SafeClientEvent.initialize() {
val activity = this@Activity

status = Status.RUNNING
creationTime = System.currentTimeMillis()
onInitialize()

LambdaEventBus.subscribe(activity)

// if (!owner.isRoot) {
// with(owner) {
// onChildInitialize(activity)
// }
// }

checkRotating(activity)

// LambdaMod.LOG.info("${System.currentTimeMillis()} Initialized $name ${System.currentTimeMillis() - ActivityManager.lastActivity.creationTime}ms after last activity creation")
}

fun SafeClientEvent.success() {
val activity = this@Activity

LambdaEventBus.unsubscribe(activity)
ListenerManager.unregister(activity)

if (activity is RenderAABBActivity) {
activity.aabbCompounds.clear()
}

parent?.let {
with(it) {
onChildSuccess(activity)
subActivities.remove(activity)
}
}

onSuccess()
checkRepeat(activity)
checkLoopingUntil(activity)

BaritoneUtils.primary?.pathingBehavior?.cancelEverything()

// LambdaMod.LOG.info("${System.currentTimeMillis()} Finalized $name after ${System.currentTimeMillis() - creationTime}ms")
// MessageSendHelper.sendRawChatMessage("$name took ${age}ms")
}

fun SafeClientEvent.failedWith(exception: Exception) {
val activity = this@Activity

MessageSendHelper.sendErrorMessage("Exception in $activityName: ${exception.message}")

if (onFailure(exception)) return

parent?.let {
with(it) {
if (childFailure(ArrayDeque(listOf(activity)), exception)) return
}
}

if (checkAttempt(activity, exception)) return

MessageSendHelper.sendErrorMessage("Fatal Exception in $activityName: ${exception.message}")

with(ActivityManager) {
cancel()
}
}

fun SafeClientEvent.cancel() {
val activity = this@Activity

onCancel()

BaritoneUtils.primary?.pathingBehavior?.cancelEverything()

subActivities.toList().forEach {
with(it) {
cancel()
}
}

parent?.let {
with(it) {
LambdaEventBus.unsubscribe(activity)
ListenerManager.unregister(activity)
subActivities.remove(activity)
}
}
}

private fun SafeClientEvent.childFailure(childActivities: ArrayDeque<Activity>, childException: Exception): Boolean {
if (onChildFailure(childActivities, childException)) return true

if (onFailure(childException)) return true

if (this@Activity is ActivityManager) {
MessageSendHelper.sendErrorMessage("Traceback: ${childException.javaClass.simpleName}: ${childException.message}\n ${childActivities.joinToString(separator = "\n ") { it.toString() }}")
return false
}

childActivities.add(this@Activity)
parent?.let {
with(it) {
childFailure(childActivities, childException)
}
}

return false
}

fun Activity.addSubActivities(activities: List<Activity>, subscribe: Boolean = false, module: AbstractModule? = null) {
if (activities.isEmpty()) return

if (depth > MAX_DEPTH) {
MessageSendHelper.sendErrorMessage("Activity depth exceeded $MAX_DEPTH!")
ActivityManager.reset()
return
}

activities.forEach { activity ->
activity.parent = this
activity.owner = module
activity.depth = depth + 1
if (subscribe) LambdaEventBus.subscribe(activity)
}

subActivities.addAll(activities)

// LambdaMod.LOG.info("${System.currentTimeMillis()} Added ${activities.size} sub activities to $name")
}

fun Activity.addSubActivities(vararg activities: Activity, subscribe: Boolean = false) {
addSubActivities(activities.toList(), subscribe)
}

fun AbstractModule.addSubActivities(vararg activities: Activity, subscribe: Boolean = false) {
addSubActivities(activities.toList(), subscribe, this)
}

enum class Status {
RUNNING,
UNINITIALIZED
}

fun appendInfo(textComponent: TextComponent, primaryColor: ColorHolder, secondaryColor: ColorHolder, details: Boolean) {
if (this !is ActivityManager) {
ListenerManager.listenerMap[this@Activity]?.let {
textComponent.add("SYNC", primaryColor)
}
ListenerManager.asyncListenerMap[this@Activity]?.let {
textComponent.add("ASYNC", primaryColor)
}

owner?.let {
textComponent.add("Module", secondaryColor)
textComponent.add(it.name, primaryColor)
}

textComponent.add("Name", secondaryColor)
textComponent.add("${javaClass.simpleName} ", primaryColor)

if (this is BuildActivity) {
textComponent.add("Context", secondaryColor)
textComponent.add(context.name, primaryColor)
textComponent.add("Availability", secondaryColor)
textComponent.add(availability.name, primaryColor)
textComponent.add("Type", secondaryColor)
textComponent.add(type.name, primaryColor)
}

textComponent.add("State", secondaryColor)
textComponent.add(status.name, primaryColor)

if (status == Status.RUNNING) {
textComponent.add("Runtime", secondaryColor)
textComponent.add(DurationFormatUtils.formatDuration(age, "HH:mm:ss,SSS"), primaryColor)
}

textComponent.add("Hash", secondaryColor)
textComponent.add(hashCode().toString(), primaryColor)

if (details) {
this::class.java.declaredFields.forEachIndexed { index, field ->
field.isAccessible = true
val name = field.name
val value = field.get(this)

// if (index.mod(6) == 0) {
// textComponent.addLine("", primaryColor)
// repeat(depth) {
// textComponent.add(" ")
// }
// }

value?.let {
if (!ActivityManagerHud.anonymize
|| !(value is BlockPos || value is Vec3d || value is Entity || value is AxisAlignedBB)
) {
textComponent.add(name.capitalize(), primaryColor)
when (value) {
is ItemBlock -> {
textComponent.add(value.block.localizedName, secondaryColor)
}
else -> {
textComponent.add(value.toString(), secondaryColor)
}
}
}
}
}
}
}

addExtraInfo(textComponent, primaryColor, secondaryColor)
textComponent.addLine("")

val acti = if (this is BuildStructure) {
subActivities
.filterIsInstance<BuildActivity>()
.sortedWith(buildComparator())
.filterIsInstance<Activity>()
} else {
subActivities
}

acti.forEach {
repeat(depth) {
textComponent.add(" ")
}
it.appendInfo(textComponent, primaryColor, secondaryColor, details)
}
}

override fun toString(): String {
val properties = this::class.java.declaredFields.joinToString(separator = ", ", prefix = ", ") {
it.isAccessible = true
val name = it.name
val value = it.get(this)
"$name=$value"
}

// return "$activityName: [State=$activityStatus, Runtime=${DurationFormatUtils.formatDuration(age, "HH:mm:ss,SSS")}, SubActivities=${subActivities.size}$properties]"
return "$activityName: [State=$status, Runtime=${DurationFormatUtils.formatDuration(age, "HH:mm:ss,SSS")}, SubActivities=${subActivities.size}]"
}
}
Loading