Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion src/main/java/com/lambda/mixin/input/KeyBindingMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import com.lambda.module.modules.movement.Speed;
import com.lambda.module.modules.movement.Sprint;
import com.lambda.module.modules.movement.TargetStrafe;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import net.minecraft.client.option.KeyBinding;
import org.spongepowered.asm.mixin.Mixin;
Expand Down
7 changes: 3 additions & 4 deletions src/main/java/com/lambda/mixin/render/ConnectScreenMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

package com.lambda.mixin.render;

import com.lambda.module.modules.combat.autodisconnect.AutoDisconnect;
import com.lambda.module.modules.combat.autodisconnect.MultiplayerReconnectTarget;
import com.lambda.module.modules.network.AutoReconnect;
import com.lambda.module.modules.network.MultiplayerReconnectTarget;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.multiplayer.ConnectScreen;
import net.minecraft.client.network.CookieStorage;
Expand All @@ -31,9 +31,8 @@

@Mixin(value = ConnectScreen.class)
public class ConnectScreenMixin {

@Inject(method = "connect(Lnet/minecraft/client/MinecraftClient;Lnet/minecraft/client/network/ServerAddress;Lnet/minecraft/client/network/ServerInfo;Lnet/minecraft/client/network/CookieStorage;)V", at= @At("HEAD"))
private void connectHead(MinecraftClient client, ServerAddress address, ServerInfo info, CookieStorage cookieStorage, CallbackInfo ci) {
AutoDisconnect.INSTANCE.setLastReconnectTarget(new MultiplayerReconnectTarget(address, info, cookieStorage));
AutoReconnect.setLastReconnectTarget(new MultiplayerReconnectTarget(address, info, cookieStorage));
}
}
111 changes: 111 additions & 0 deletions src/main/java/com/lambda/mixin/render/DisconnectedScreenMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright 2026 Lambda
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.lambda.mixin.render;

import com.lambda.module.modules.network.AutoReconnect;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.DisconnectedScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.DirectionalLayoutWidget;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import java.util.Locale;

@Mixin(DisconnectedScreen.class)
public abstract class DisconnectedScreenMixin extends Screen {
@Shadow @Final private DirectionalLayoutWidget grid;
@Shadow @Final private Screen parent;

@Unique
private ButtonWidget lambda$reconnectButton;

@Unique
private long lambda$autoReconnectTime = -1L;

@Unique
private boolean lambda$reconnected = false;

protected DisconnectedScreenMixin(Text title) {
super(title);
}

@Inject(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;isMultiplayerEnabled()Z"))
private void addReconnectButton(CallbackInfo ci) {
lambda$reconnected = false;

boolean hasTarget = AutoReconnect.getLastReconnectTarget() != null;
if (AutoReconnect.canAutoReconnect()) {
lambda$autoReconnectTime = System.currentTimeMillis() + (long) (AutoReconnect.INSTANCE.getDelay() * 1000.0);
} else {
lambda$autoReconnectTime = -1L;
}

lambda$reconnectButton = ButtonWidget.builder(lambda$getButtonText(), button -> {
lambda$reconnected = true;
AutoReconnect.reconnect(this.parent);
}).width(200).build();

lambda$reconnectButton.active = hasTarget;
this.grid.add(lambda$reconnectButton);
}

@Override
public void render(DrawContext context, int mouseX, int mouseY, float deltaTicks) {
super.render(context, mouseX, mouseY, deltaTicks);

if (lambda$reconnectButton == null || lambda$reconnected) return;

if (AutoReconnect.canAutoReconnect() && lambda$autoReconnectTime > 0) {
long remainingMillis = lambda$autoReconnectTime - System.currentTimeMillis();
if (remainingMillis <= 0) {
lambda$reconnected = true;
AutoReconnect.reconnect(this.parent);
} else {
double remainingSeconds = remainingMillis / 1000.0;
lambda$reconnectButton.setMessage(Text.literal(String.format(Locale.ROOT, "Reconnect (%.1fs)", remainingSeconds)));
}
} else {
lambda$reconnectButton.setMessage(Text.literal("Reconnect"));
}
}

@Override
public void removed() {
super.removed();
lambda$autoReconnectTime = -1L;
lambda$reconnected = true;
}

@Unique
private Text lambda$getButtonText() {
if (AutoReconnect.canAutoReconnect() && lambda$autoReconnectTime > 0) {
long remainingMillis = Math.max(0, lambda$autoReconnectTime - System.currentTimeMillis());
double remainingSeconds = remainingMillis / 1000.0;
return Text.literal(String.format(Locale.ROOT, "Reconnect (%.1fs)", remainingSeconds));
}
return Text.literal("Reconnect");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

package com.lambda.mixin.world;

import com.lambda.module.modules.combat.autodisconnect.AutoDisconnect;
import com.lambda.module.modules.combat.autodisconnect.SingleplayerReconnectTarget;
import com.lambda.module.modules.network.AutoReconnect;
import com.lambda.module.modules.network.SingleplayerReconnectTarget;
import net.minecraft.server.integrated.IntegratedServerLoader;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
Expand All @@ -29,7 +29,6 @@
public class IntegratedServerLoaderMixin {
@Inject(method = "start(Ljava/lang/String;Ljava/lang/Runnable;)V", at = @At("HEAD"))
private void onStart(String name, Runnable onCancel, CallbackInfo ci) {
AutoDisconnect.INSTANCE.setLastReconnectTarget(new SingleplayerReconnectTarget(name));
AutoReconnect.setLastReconnectTarget(new SingleplayerReconnectTarget(name));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import com.lambda.event.Muteable
import com.lambda.event.events.ButtonEvent
import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe
import com.lambda.gui.dsl.ImGuiBuilder
import com.lambda.imgui.ImGui.isMouseClicked
import com.lambda.imgui.flag.ImGuiCol
import com.lambda.imgui.flag.ImGuiHoveredFlags
import com.lambda.imgui.flag.ImGuiMouseButton
Expand Down
1 change: 0 additions & 1 deletion src/main/kotlin/com/lambda/gui/MenuBar.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import com.lambda.gui.components.QuickSearch
import com.lambda.gui.components.SettingsWidget.buildConfigSettingsContext
import com.lambda.gui.dsl.ImGuiBuilder
import com.lambda.imgui.ImGui
import com.lambda.imgui.ImGui.closeCurrentPopup
import com.lambda.imgui.flag.ImGuiCol
import com.lambda.imgui.flag.ImGuiStyleVar
import com.lambda.imgui.flag.ImGuiWindowFlags
Expand Down
4 changes: 2 additions & 2 deletions src/main/kotlin/com/lambda/gui/dsl/ImGuiBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
package com.lambda.gui.dsl

import com.lambda.gui.components.ClickGuiLayout
import com.lambda.gui.dsl.ImGuiBuilder.onItemClick
import com.lambda.gui.dsl.ImGuiBuilder.onItemHover
import com.lambda.gui.dsl.ImGuiBuilder.openPopup
import com.lambda.gui.dsl.ImGuiBuilder.text
import com.lambda.imgui.ImDrawList
Expand Down Expand Up @@ -108,10 +110,8 @@ import com.lambda.imgui.ImGui.isItemEdited
import com.lambda.imgui.ImGui.isItemFocused
import com.lambda.imgui.ImGui.isItemHovered
import com.lambda.imgui.ImGui.isItemToggledOpen
import com.lambda.imgui.ImGui.isMouseClicked
import com.lambda.imgui.ImGui.isWindowAppearing
import com.lambda.imgui.ImGui.isWindowCollapsed
import com.lambda.imgui.ImGui.isWindowHovered
import com.lambda.imgui.ImGui.plotHistogram
import com.lambda.imgui.ImGui.plotLines
import com.lambda.imgui.ImGui.popFont
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import com.lambda.interaction.handlers.ContainerHandler
import com.lambda.interaction.material.container.ExternalContainer
import com.lambda.interaction.material.container.MaterialContainer
import com.lambda.task.Task
import com.lambda.task.wrappers.TaskSupplier
import com.lambda.task.tasks.OpenContainerTask
import com.lambda.task.wrappers.TaskSupplier
import com.lambda.task.wrappers.thenAction
import com.lambda.util.extension.containerSlots
import com.lambda.util.text.buildText
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ import com.lambda.interaction.handlers.ContainerHandler.findSlotsWithMaterial
import com.lambda.interaction.material.StackSelection.Companion.select
import com.lambda.interaction.material.container.ExternalContainer
import com.lambda.interaction.material.container.MaterialContainer
import com.lambda.task.wrappers.TaskSupplier
import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock
import com.lambda.task.tasks.OpenContainerTask
import com.lambda.task.tasks.PlaceContainerTask
import com.lambda.task.wrappers.TaskSupplier
import com.lambda.task.wrappers.thenAction
import com.lambda.task.wrappers.thenOrNull
import com.lambda.util.extension.containerSlots
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ import com.lambda.context.SafeContext
import com.lambda.interaction.handlers.ContainerHandler
import com.lambda.interaction.material.container.ExternalContainer
import com.lambda.interaction.material.container.MaterialContainer
import com.lambda.task.wrappers.TaskSupplier
import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock
import com.lambda.task.tasks.OpenContainerTask
import com.lambda.task.tasks.PlaceContainerTask
import com.lambda.task.wrappers.TaskSupplier
import com.lambda.task.wrappers.thenAction
import com.lambda.task.wrappers.thenOrNull
import com.lambda.threading.runSafe
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen
import com.lambda.gui.components.ClickGuiLayout
import com.lambda.interaction.handlers.FriendHandler
import com.lambda.module.Module
import com.lambda.module.modules.network.AutoReconnect
import com.lambda.module.tag.ModuleTag
import com.lambda.sound.SoundHandler.playSound
import com.lambda.util.CommunicationUtils
Expand Down Expand Up @@ -56,9 +57,6 @@ import com.lambda.util.text.literal
import com.lambda.util.text.text
import com.lambda.util.world.WorldUtils.isLoaded
import com.lambda.util.world.fastEntitySearch
import net.minecraft.client.network.CookieStorage
import net.minecraft.client.network.ServerAddress
import net.minecraft.client.network.ServerInfo
import net.minecraft.client.texture.NativeImageBackedTexture
import net.minecraft.client.util.ScreenshotRecorder
import net.minecraft.component.DataComponentTypes
Expand Down Expand Up @@ -194,6 +192,7 @@ object AutoDisconnect : Module(
@Tab(TRIGGERS_TAB) @Group(DAMAGE_TRIGGER_GROUP) private val arrow by setting("Arrow", false, "Disconnect from the server when you take arrow damage.") { damage }
@Tab(TRIGGERS_TAB) @Group(DAMAGE_TRIGGER_GROUP) private val trident by setting("Trident", false, "Disconnect from the server when you take trident damage.") { damage }

@Tab(GENERAL_TAB) private val disableAutoReconnect by setting("Disable ${AutoReconnect.name}", false, "Disables ${AutoReconnect.name} when disconnecting")
@Tab(GENERAL_TAB) @Group(PACKET_DISCONNECT_GROUP) private val invalidHotbarDisconnect by setting("Select Invalid Hotbar Slot", false, "Sends an invalid hotbar selection to force the server to kick the player")
@Tab(GENERAL_TAB) @Group(PACKET_DISCONNECT_GROUP) private val attackSelfDisconnect by setting("Attack Self", false, "Sends an attack self packet to force the server to kick the player")
@Tab(GENERAL_TAB) @Group(PACKET_DISCONNECT_GROUP) private val impossibleTimestampChatDisconnect by setting("Send Impossible Chat Timestamp", false, "Sends a chat message with an impossible timestamp to force the server to kick the player")
Expand All @@ -205,7 +204,6 @@ object AutoDisconnect : Module(
private var disconnectDetails: DisconnectDetails? = null
private var disconnectInProgress: Boolean = false
private val joinTimer = TickTimer()
var lastReconnectTarget: ReconnectTarget? = null

init {
listen<TickEvent.Pre> {
Expand Down Expand Up @@ -303,6 +301,7 @@ object AutoDisconnect : Module(
private fun SafeContext.requestDisconnect(reasonText: Text, disarmedTrigger: Reason? = null): Boolean {
if (player.gameMode != GameMode.SURVIVAL && player.gameMode != GameMode.ADVENTURE || disconnectInProgress) return false
disconnectInProgress = true
if (AutoReconnect.isEnabled && disableAutoReconnect) AutoReconnect.disable()
ScreenshotRecorder.takeScreenshot(Lambda.mc.framebuffer, 1) { image ->
val imageIdentifier = Identifier.of("lambda", "auto_disconnect_screenshot")
val texture = NativeImageBackedTexture({ "auto-disconnect-screenshot" }, image)
Expand Down Expand Up @@ -913,16 +912,4 @@ data class DisconnectDetails(
val reason: Text,
val sections: List<DetailSection>,
val hideDetails: Boolean
)

sealed interface ReconnectTarget

data class MultiplayerReconnectTarget(
val address: ServerAddress,
val info: ServerInfo,
val cookieStorage: CookieStorage?
) : ReconnectTarget

data class SingleplayerReconnectTarget(
val levelName: String
) : ReconnectTarget
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
package com.lambda.module.modules.combat.autodisconnect

import com.lambda.gui.OverlayBackgroundScreen
import com.lambda.module.modules.network.AutoReconnect
import com.lambda.module.modules.network.MultiplayerReconnectTarget
import com.lambda.module.modules.network.SingleplayerReconnectTarget
import com.lambda.util.render.CursorOverrideProvider
import net.minecraft.client.gl.RenderPipelines
import net.minecraft.client.gui.Click
Expand Down Expand Up @@ -127,7 +130,7 @@ class AutoDisconnectScreen(

private fun reconnect() {
releaseTexture()
when (val target = AutoDisconnect.lastReconnectTarget) {
when (val target = AutoReconnect.lastReconnectTarget) {
is MultiplayerReconnectTarget -> {
ConnectScreen.connect(parent, client, target.address, target.info, false, target.cookieStorage)
}
Expand All @@ -145,7 +148,7 @@ class AutoDisconnectScreen(
private fun openWorldListScreen() {
releaseTexture()
client?.setScreen(
when (AutoDisconnect.lastReconnectTarget) {
when (AutoReconnect.lastReconnectTarget) {
is SingleplayerReconnectTarget -> SelectWorldScreen(parent)
else -> MultiplayerScreen(parent)
}
Expand Down Expand Up @@ -249,15 +252,15 @@ class AutoDisconnectScreen(
}

private fun updateReconnectButton() {
reconnectButton.active = AutoDisconnect.lastReconnectTarget != null
reconnectButton.active = AutoReconnect.lastReconnectTarget != null
}

private fun detailToggleText() =
Text.literal(if (showDetails) "Hide Details" else "Show Details")

private fun listButtonText() =
Text.literal(
when (AutoDisconnect.lastReconnectTarget) {
when (AutoReconnect.lastReconnectTarget) {
is SingleplayerReconnectTarget -> "World List"
else -> "Server List"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ import com.lambda.interaction.material.StackSelection
import com.lambda.interaction.material.container.containers.HotbarContainer
import com.lambda.interaction.material.container.containers.OffHandContainer
import com.lambda.module.modules.combat.crystalaura.CrystalAura.ActionType
import com.lambda.module.modules.combat.crystalaura.CrystalAura.PredictionMode
import com.lambda.module.modules.combat.crystalaura.CrystalAura.crystalPosition
import com.lambda.module.modules.combat.crystalaura.CrystalAura.explodeDelay
import com.lambda.module.modules.combat.crystalaura.CrystalAuraExploding.explodeInternal
import com.lambda.module.modules.combat.crystalaura.CrystalAura.explodeTimer
import com.lambda.module.modules.combat.crystalaura.CrystalAura.lastEntityId
import com.lambda.module.modules.combat.crystalaura.CrystalAura.lastHit
Expand All @@ -48,7 +46,7 @@ import com.lambda.module.modules.combat.crystalaura.CrystalAura.rotate
import com.lambda.module.modules.combat.crystalaura.CrystalAura.safeToPlaceInstantly
import com.lambda.module.modules.combat.crystalaura.CrystalAura.swap
import com.lambda.module.modules.combat.crystalaura.CrystalAura.swapHand
import com.lambda.module.modules.combat.crystalaura.CrystalAura.waitingForCrystal
import com.lambda.module.modules.combat.crystalaura.CrystalAuraExploding.explodeInternal
import com.lambda.module.modules.combat.crystalaura.CrystalAuraPlacing.placeInternal
import com.lambda.threading.runSafe
import com.lambda.threading.runSafeAutomated
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@

package com.lambda.module.modules.movement

import com.lambda.config.forEachSetting
import com.lambda.config.hideAllExcept
import com.lambda.config.blocks.WorldLineSettings
import com.lambda.config.forEachSetting
import com.lambda.config.hideAllExcept
Expand All @@ -39,6 +37,7 @@ import kotlin.math.cos
import kotlin.math.sin
import kotlin.math.sqrt

@Suppress("unused")
object TargetStrafe : Module(
name = "TargetStrafe",
description = "Strafes around a target in a circle. The default settings work great for old NCP.",
Expand Down
Loading