Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: ActivitySystem, BuildTools, HighwayTools #567

Draft
wants to merge 109 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
109 commits
Select commit Hold shift + click to select a range
091de91
Added ActivityManager and Activity abstract class
minecraft-simon Dec 13, 2022
e5100ca
More tests
Avanatiker Dec 13, 2022
7fadcd8
First working activity system with example
Avanatiker Dec 14, 2022
3d105f5
Implemented HUD and InventoryTransactions
Avanatiker Dec 15, 2022
ba0d1ec
Generic info gather
Avanatiker Dec 15, 2022
b95badf
Inventory stuff
Avanatiker Dec 15, 2022
d16fee7
PlaceBlockActivity and type tests
Avanatiker Dec 15, 2022
fc26aeb
Multi types using interfaces
Avanatiker Dec 16, 2022
073c78d
Added render block interface
Avanatiker Dec 16, 2022
d0066f8
Added BreakBlockActivity and some sketches
Avanatiker Dec 16, 2022
fe15918
Extract item from container
Avanatiker Dec 17, 2022
e1e5b2b
Added CustomGoalActivity
Avanatiker Dec 18, 2022
7d33b7b
Remove not working code
Avanatiker Dec 18, 2022
87f9d65
Added Storage Management
Avanatiker Dec 18, 2022
8f44320
Refactor names and small stuff
Avanatiker Dec 19, 2022
4b5edb3
Owner property added
Avanatiker Dec 19, 2022
1e6065a
Move package
Avanatiker Dec 22, 2022
3df5d25
Test case for listener
Avanatiker Dec 22, 2022
fd20991
Fix for listening objects
Avanatiker Dec 22, 2022
79ee5d3
Added BreakDownEnderChests
Avanatiker Dec 22, 2022
b74af73
Cleanup
Avanatiker Dec 22, 2022
2ff065c
Rotation and timing optimizations
Avanatiker Dec 23, 2022
0f660aa
Remove unneeded activity
Avanatiker Dec 23, 2022
952fe6c
Sketch: Inventory 2.0
Avanatiker Dec 27, 2022
ed0e315
Cleanup
Avanatiker Dec 28, 2022
7cfeedd
First BuildBlockState test
Avanatiker Dec 28, 2022
0d89f02
added some activities for auto-xp
minecraft-simon Dec 29, 2022
4058137
General throwable usage
Avanatiker Dec 30, 2022
c6afc0b
Iterative instant activity updates
Avanatiker Dec 30, 2022
5e91ba7
Added LoopingAmountActivity type
Avanatiker Dec 30, 2022
cb672e4
Added LoopingUntilActivity type and removed CompoundActivity
Avanatiker Dec 30, 2022
566cfde
Change example
Avanatiker Dec 30, 2022
a1d45df
proposal for activity events
minecraft-simon Dec 30, 2022
b4a41c5
Use instead of SetState
Avanatiker Dec 30, 2022
5a23c0b
Fix stuff
Avanatiker Dec 30, 2022
d0ff8d8
Add anon option to hud
Avanatiker Dec 30, 2022
b730d34
Fix collecting drops
Avanatiker Dec 31, 2022
3b77940
Exception system
Avanatiker Jan 2, 2023
124d9f9
Decision chains and exception improvement
Avanatiker Jan 2, 2023
1485693
Big refactor for exception handling
Avanatiker Jan 3, 2023
4c91c27
Fix the InventoryManagerTwo sketch
Avanatiker Jan 3, 2023
3d357b4
Macro and micro management
Avanatiker Jan 10, 2023
afc3ac7
Module is now Activity
Avanatiker Jan 10, 2023
db87387
Formatting refactor
Avanatiker Jan 10, 2023
ffaeb79
Not yet
Avanatiker Jan 10, 2023
49ea2cf
Fix PlaceBlock timeout
Avanatiker Jan 10, 2023
ea28a28
Tweaks for structure building
Avanatiker Jan 10, 2023
2eac4ae
Bring back ignored blocks
Avanatiker Jan 10, 2023
756f318
Added working HighwayTools prototype
Avanatiker Jan 13, 2023
29b255a
Commands and cleanup
Avanatiker Jan 13, 2023
d0b37d3
BuildBlock context system and rainbow highway
Avanatiker Jan 14, 2023
c433670
Stash dump
Avanatiker Jan 26, 2023
b4b44ac
Support EnumFacing blocks, fixed item dump
Avanatiker Jan 30, 2023
52e691c
Schematica API
rfresh2 Jan 26, 2023
5f0b980
Build schematic activity
rfresh2 Jan 28, 2023
0a3ed43
rename
rfresh2 Jan 28, 2023
90dd2f8
Add SchematicBuilder module
Avanatiker Jan 30, 2023
a0053f8
Creative mode support and fixes
Avanatiker Jan 31, 2023
14f13bb
Added HalfBlock placements
Avanatiker Feb 2, 2023
b2d1749
Fix block meta data and block rotations
Avanatiker Feb 2, 2023
74ea596
Add TrapDoors and Strairs support
Avanatiker Feb 2, 2023
cdb03b5
Added Button support
Avanatiker Feb 2, 2023
72f392b
State properties rewrite and render fix
Avanatiker Feb 16, 2023
c1e2df1
Better UP and BOTTOM place. Fix absent Schematica crash
Avanatiker Feb 19, 2023
d98d403
Fix ItemBlockSpecials
Avanatiker Feb 20, 2023
a70cdba
Fix optimal stack calcultion
Avanatiker Feb 20, 2023
11e5ce7
Place and Break rewrite and improved concurrent building
Avanatiker Feb 20, 2023
e81fc22
Fix block replacement
Avanatiker Feb 20, 2023
c5ca532
Fix boxed tasks
Avanatiker Feb 20, 2023
23be96e
Adding concurrent build actions
Avanatiker Feb 22, 2023
140dc0f
Fix build order structure
Avanatiker Feb 24, 2023
c3f9e94
Revert to ConcurrentLinkedDeque and fancy break particles
Avanatiker Feb 26, 2023
8123508
Best tool for mining
Avanatiker Feb 26, 2023
f209f00
Smol fixes
Avanatiker Feb 26, 2023
060f544
Thread sanitizing and other fixes
Avanatiker Mar 3, 2023
2d6d57b
Optimal tool selection and other optimizations
Avanatiker Mar 6, 2023
83ec46c
Fix attempting activities and skipping ignore blocks
Avanatiker Mar 7, 2023
6a6d71c
Lots of fixes
Avanatiker Mar 10, 2023
1ea6db1
Clean up
Avanatiker Mar 12, 2023
20cf137
Multi module support
Avanatiker Mar 12, 2023
40590f8
Fix build
Avanatiker Mar 12, 2023
4dbaeb6
Fix no autopathing
Avanatiker Mar 13, 2023
37d72b6
Elevate path finding into BuildStructure
Avanatiker Mar 16, 2023
d35a7d4
Rewrote priority system for BuildStructure
Avanatiker Mar 26, 2023
16daa96
Added overlay debug renderer and fix breaking bushes
Avanatiker Mar 27, 2023
9d69194
Add render settings and graffiti module
Avanatiker May 5, 2023
077e869
Fix Graffiti logic
Avanatiker May 5, 2023
0d7987e
Graffiti, StorageManagement, BlockPos setting and auto crafting
Avanatiker May 29, 2023
d47d22e
Quality of life settings for WorldEater
Avanatiker Jun 3, 2023
b91b1f8
Fix rebase fail
Avanatiker Jun 5, 2023
c9bba67
Merge branch 'master' into activitySystem
Avanatiker Jun 5, 2023
775a5c2
HWT start command
Avanatiker Jun 5, 2023
0d892f3
fix item serializer
rfresh2 Jun 5, 2023
f5837b8
fix activities aabb messing up rendering scaling
rfresh2 Jun 6, 2023
85fcdf1
fix possible break conflicts with baritone goals. fix repeating activ…
rfresh2 Jul 11, 2023
5267703
Merge remote-tracking branch 'origin/master' into activity_system
Avanatiker Jul 12, 2023
2ec2145
Merge branch 'master' into activity_system
Avanatiker Jul 15, 2023
92e9aa8
Add StashTransaction sketch
Avanatiker Jul 16, 2023
292c68c
fixes, optimizations, and crash preventions
rfresh2 Jul 16, 2023
dddb2ba
Fix break reset
Avanatiker Jul 16, 2023
c0bd835
Improved inventory action data propagation
Avanatiker Aug 6, 2023
a11a23c
Make pathfinding actually kinda work
Avanatiker Aug 7, 2023
431b863
Fixing pathing bugs and more efficient item collecting
Avanatiker Aug 7, 2023
0dcae9e
Mob repelling, WorldEater HUD, qol
Avanatiker Aug 7, 2023
fd33de3
Cleanup
Avanatiker Aug 7, 2023
7c0558a
Merge branch 'master' into activity_system
Avanatiker Aug 8, 2023
624f1c3
Merge branch 'master' into activity_system
Avanatiker Aug 8, 2023
856f5f4
First minimum viable product of WorldEater
Avanatiker Aug 9, 2023
02d3d64
Full predicate logic selection support
Avanatiker Aug 12, 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
357 changes: 357 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,357 @@
package com.lambda.client.activity

import com.lambda.client.LambdaMod
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
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.gui.hudgui.elements.client.ActivityManagerHud.maxEntries
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)
if (activity !is RepeatingActivity) ListenerManager.unregister(activity)

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

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

onSuccess()
checkRepeat(activity)
checkLoopingUntil(activity)

if (this@Activity !is BuildActivity) 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

LambdaMod.LOG.warn("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) {
LambdaMod.LOG.warn("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.forEach { field ->
field.isAccessible = true
val name = field.name
val value = field.get(this) ?: return@forEach

if (ActivityManagerHud.anonymize && (value is BlockPos || value is Vec3d || value is Entity || value is AxisAlignedBB)) return@forEach

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 activities = if (this is BuildStructure) {
subActivities
.filterIsInstance<BuildActivity>()
.sortedWith(buildComparator())
.filterIsInstance<Activity>()
} else {
subActivities
}

activities.take(maxEntries).forEach {
repeat(depth) {
textComponent.add(" ")
}
it.appendInfo(textComponent, primaryColor, secondaryColor, details)
}
if (activities.size > maxEntries) {
repeat(depth) {
textComponent.add(" ")
}
textComponent.addLine("And ${activities.size - maxEntries} more...", primaryColor)
}
}

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