-
-
Notifications
You must be signed in to change notification settings - Fork 493
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
feat(Nextgen): Baritone Integration #4918
base: nextgen
Are you sure you want to change the base?
feat(Nextgen): Baritone Integration #4918
Conversation
great |
@1zun4 please fix the freecam and baritone conflicts, I can't do it as I haven't quite figured out the codebase yet |
src/main/kotlin/net/ccbluex/liquidbounce/features/module/ModuleManager.kt
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just wanted to say that the way the settings are made is just beautiful. Lol.
Sure, I will do that. |
thank u |
src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/ModuleAutoWalk.kt
Outdated
Show resolved
Hide resolved
Fix it: the [MovementInputEvent] is no longer called when the baritone is pathing |
i think we need to rewrite baritone's [LookBehavior] to fix all rotations & interact issues 2024-12-17.07-25-51.mp4 |
todo: fix baritone interactions through freecam 2024-12-17.14-58-37.mp4 |
…!= null) & auto walk disables when path is canceled
The only thing left to fix is todo: fix baritone interactions through freecam. |
Current settings structure (in gui):
|
src/main/java/net/ccbluex/liquidbounce/injection/mixins/baritone/MixinCustomGoalProcess.java
Outdated
Show resolved
Hide resolved
src/main/java/net/ccbluex/liquidbounce/injection/mixins/baritone/MixinBaritone.java
Outdated
Show resolved
Hide resolved
...in/kotlin/net/ccbluex/liquidbounce/features/module/modules/combat/killaura/ModuleKillAura.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/player/ModuleAutoWalk.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/client/ModuleBaritone.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/client/ModuleBaritone.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/client/ModuleBaritone.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/client/ModuleBaritone.kt
Outdated
Show resolved
Hide resolved
src/main/kotlin/net/ccbluex/liquidbounce/features/module/modules/client/ModuleBaritone.kt
Outdated
Show resolved
Hide resolved
2024-12-19.18-19-46.mp4 |
all tasks were done |
src/main/java/net/ccbluex/liquidbounce/injection/mixins/baritone/MixinSetCommand.java
Outdated
Show resolved
Hide resolved
src/main/kotlin/net/ccbluex/liquidbounce/utils/entity/EntityExtensions.kt
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is impressive work overall. Don't be bothered by the big number of complaints. This is a big feature with big changes. 1.5 complaints per 100 lines is not a lot under these circumstances!
@Inject(method = "tick", at = @At("HEAD")) | ||
public void hookTick(boolean par1, float par2, CallbackInfo ci) { | ||
var options = MinecraftClient.getInstance().options; | ||
|
||
this.proceedKeyboardTick(new DirectionalInput( | ||
options.forwardKey.isPressed(), | ||
options.backKey.isPressed(), | ||
options.leftKey.isPressed(), | ||
options.rightKey.isPressed() | ||
), options.jumpKey.isPressed(), options.sneakKey.isPressed(), false, () -> {}); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure that this is the desired behavior? If LiquidBounce forced the W keybind to be on and the player pressed W at the same time, the moveForward value would end up at 2.0
(MixinInput.proceedKeyboardTick + PlayerMovementInput.tick)
@Mixin(SetCommand.class) | ||
public class MixinSetCommand { | ||
|
||
@Inject(method = "execute", at = @At(value = "INVOKE", target = "Lbaritone/command/defaults/SetCommand;logDirect(Ljava/lang/String;)V", ordinal = 9), remap = false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a terrible injection point. This does not consider other code that might change the setting (bypassing the command). Additionally, using ordinal
guarantees that the injection point breaks with the next baritone release.
/** | ||
* A mutable map for controlling Baritone settings through client-side wrapper ([ModuleBaritone]) settings. | ||
* | ||
* The map key represents a Baritone setting ([Settings.Setting]), | ||
* and the value is a lambda function that serves as a setter for updating the setting's value. | ||
* | ||
* The lambda accepts the current setting value of type [Any], corresponding to | ||
* the generic type T of the original [Settings.Setting.value]. | ||
* | ||
* Used for dynamic management and synchronization of Baritone settings | ||
* through intermediate client-side settings. | ||
* | ||
* @see Settings.Setting | ||
* @see MixinSetCommand | ||
*/ | ||
private val controlledBaritoneSettingsMutableMap = mutableMapOf<Settings.Setting<*>, (Any) -> Unit>() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good documentation 👍🏻
But it wouldn't need to be that verbose if you used "anonymous" function pointers ((Any) -> Unit
) as a value type. I'd recommend using an interface for that, like:
private interface BaritoneSettingHandle<T> {
/**
* Accepts the current setting value of type [Any], corresponding to
* the generic type T of the original [Settings.Setting.value].
*/
fun onChange(newValue: T)
}
/** | ||
* Provides read-only access to the controlled Baritone settings map. | ||
* | ||
* This getter exposes the internal [controlledBaritoneSettingsMutableMap] | ||
* as an immutable [Map], preventing direct modifications from outside the class. | ||
* | ||
* Contains Baritone settings mapped to their respective setter lambdas, | ||
* where each lambda can update the corresponding setting's value. | ||
* | ||
* @return An immutable map of Baritone settings and their setter functions | ||
*/ | ||
val controlledBaritoneSettings: Map<Settings.Setting<*>, (Any) -> Unit> get() = controlledBaritoneSettingsMutableMap |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again: If you have much documentation for a little, simple piece of code, there is probably something wrong with it.
I think the problem here is that you implemented the feature in the wrong place, here is what I mean:
The functionality of registering changes of a baritone setting is a feature of ModuleBaritone
. It must implement it. The caller should not care about how it is implemented.
But you have big parts of the implementation in MixinSetCommand?
:
var onChangeListener = ModuleBaritoneKt.getControlledBaritoneSettings()
.getOrDefault(setting, null);
if(onChangeListener != null) {
onChangeListener.invoke(setting.value);
}
The mixin code isn't responsible for deciding what happens if the given setting is unknown. The mixin isn't responsible for looking it up in the first place. It's only job is to call ModuleBaritone.notifySettingChange
(or a different name).
fun cleanup() { | ||
unlock() | ||
fun cleanup(unpauseBaritone: Boolean = false) { | ||
unlock(unpauseBaritone = unpauseBaritone) | ||
} | ||
|
||
fun lock(entity: LivingEntity, reportToUI: Boolean = true) { | ||
fun lock(entity: LivingEntity, reportToUI: Boolean = true, pauseBaritone: Boolean = false) { | ||
lockedOnTarget = entity | ||
|
||
if (pauseBaritone && PathManager.isPathing) { | ||
PathManager.pause() | ||
} | ||
|
||
if (entity is PlayerEntity && reportToUI) { | ||
EventManager.callEvent(TargetChangeEvent(PlayerData.fromPlayer(entity))) | ||
} | ||
} | ||
|
||
private fun unlock() { | ||
private fun unlock(unpauseBaritone: Boolean = false) { | ||
lockedOnTarget = null | ||
|
||
if (unpauseBaritone && PathManager.hasPath) { | ||
PathManager.resume() | ||
} | ||
} | ||
|
||
fun validateLock(validator: (Entity) -> Boolean) { | ||
fun validateLock(unpauseBaritone: Boolean = false, validator: (Entity) -> Boolean) { | ||
val lockedOnTarget = lockedOnTarget ?: return | ||
|
||
if (!validate(lockedOnTarget) || !validator(lockedOnTarget)) { | ||
this.lockedOnTarget = null | ||
unlock(unpauseBaritone) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dislike that pauseBaritone
is implemented in TargetTracker
, while it is only a feature of KillAura. (If something is not a feature of a class, it should be never implemented there!)
The solution: Dependency injection:
class TargetTracker(
// ...
changeListener: ChangeListener = ChangeListener.Default
// ...
) {
// ...
interface ChangeListener {
fun onLock(newTarget: Entity)
fun onUnlock(oldTarget: Entity)
object Default : ChangeListener {
// ...
}
}
// ...
|
||
fun shouldDisableRotations() = running && !allowRotationChange | ||
fun shouldDisableRotations() = running && !allowRotationChange && !PathManager.isPathing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DRY. !allowRotationChange && !PathManager.isPathing
is three times in this file. Bugs will occur when someone only changes one of them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(100% unfunny joke start) I will repeat myself.
I will repeat myself.
I will repeat myself. (100% unfunny joke end)
* - This interface supports basic pathing operations such as moving to a specific position, pausing, resuming, | ||
* and stopping an active path. | ||
*/ | ||
interface PathManager { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, very good documentation 👍🏻
fun stop() {} | ||
|
||
companion object : PathManager { | ||
private val Default by lazy { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming convention
* if (!PathManager) { ... } | ||
* ``` | ||
* and | ||
* ``` | ||
* if (!PathManager.isBaritone) { ... } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you ask the question if not PathManager, do this else do that, the user expects the statement to do something like if PathManager is not null, ... while it really is if Baritone Pathing is available, ....
Kotlin has these cool features (like the not()
operator) , but reducing the code intuitiveness by using them is not helpful.
# Conflicts: # src/main/kotlin/net/ccbluex/liquidbounce/features/module/ModuleManager.kt # src/main/resources/assets/liquidbounce/lang/en_us.json
Co-authored-by: ManInMyVan <[email protected]>
Co-authored-by: ManInMyVan <[email protected]>
Baritone integration for [FEATURE] Add baritone integration? #4892
(for 1.21.1 i found & used this baritone fork by MeteorDevelopment
TODOs
2024-12-16.20-38-15.mp4
2024-12-16.18-56-40.mp4