Skip to content

Commit 001863a

Browse files
authored
Feature: Add #243 AutoReconnect module and reconnect button (#335)
1 parent f59559c commit 001863a

16 files changed

Lines changed: 216 additions & 42 deletions

File tree

‎src/main/java/com/lambda/mixin/input/KeyBindingMixin.java‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
import com.lambda.module.modules.movement.Speed;
2121
import com.lambda.module.modules.movement.Sprint;
22-
import com.lambda.module.modules.movement.TargetStrafe;
2322
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
2423
import net.minecraft.client.option.KeyBinding;
2524
import org.spongepowered.asm.mixin.Mixin;

‎src/main/java/com/lambda/mixin/render/ConnectScreenMixin.java‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717

1818
package com.lambda.mixin.render;
1919

20-
import com.lambda.module.modules.combat.autodisconnect.AutoDisconnect;
21-
import com.lambda.module.modules.combat.autodisconnect.MultiplayerReconnectTarget;
20+
import com.lambda.module.modules.network.AutoReconnect;
21+
import com.lambda.module.modules.network.MultiplayerReconnectTarget;
2222
import net.minecraft.client.MinecraftClient;
2323
import net.minecraft.client.gui.screen.multiplayer.ConnectScreen;
2424
import net.minecraft.client.network.CookieStorage;
@@ -31,9 +31,8 @@
3131

3232
@Mixin(value = ConnectScreen.class)
3333
public class ConnectScreenMixin {
34-
3534
@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"))
3635
private void connectHead(MinecraftClient client, ServerAddress address, ServerInfo info, CookieStorage cookieStorage, CallbackInfo ci) {
37-
AutoDisconnect.INSTANCE.setLastReconnectTarget(new MultiplayerReconnectTarget(address, info, cookieStorage));
36+
AutoReconnect.setLastReconnectTarget(new MultiplayerReconnectTarget(address, info, cookieStorage));
3837
}
3938
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright 2026 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.mixin.render;
19+
20+
import com.lambda.module.modules.network.AutoReconnect;
21+
import net.minecraft.client.gui.DrawContext;
22+
import net.minecraft.client.gui.screen.DisconnectedScreen;
23+
import net.minecraft.client.gui.screen.Screen;
24+
import net.minecraft.client.gui.widget.ButtonWidget;
25+
import net.minecraft.client.gui.widget.DirectionalLayoutWidget;
26+
import net.minecraft.text.Text;
27+
import org.spongepowered.asm.mixin.Final;
28+
import org.spongepowered.asm.mixin.Mixin;
29+
import org.spongepowered.asm.mixin.Shadow;
30+
import org.spongepowered.asm.mixin.Unique;
31+
import org.spongepowered.asm.mixin.injection.At;
32+
import org.spongepowered.asm.mixin.injection.Inject;
33+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
34+
35+
import java.util.Locale;
36+
37+
@Mixin(DisconnectedScreen.class)
38+
public abstract class DisconnectedScreenMixin extends Screen {
39+
@Shadow @Final private DirectionalLayoutWidget grid;
40+
@Shadow @Final private Screen parent;
41+
42+
@Unique
43+
private ButtonWidget lambda$reconnectButton;
44+
45+
@Unique
46+
private long lambda$autoReconnectTime = -1L;
47+
48+
@Unique
49+
private boolean lambda$reconnected = false;
50+
51+
protected DisconnectedScreenMixin(Text title) {
52+
super(title);
53+
}
54+
55+
@Inject(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;isMultiplayerEnabled()Z"))
56+
private void addReconnectButton(CallbackInfo ci) {
57+
lambda$reconnected = false;
58+
59+
boolean hasTarget = AutoReconnect.getLastReconnectTarget() != null;
60+
if (AutoReconnect.canAutoReconnect()) {
61+
lambda$autoReconnectTime = System.currentTimeMillis() + (long) (AutoReconnect.INSTANCE.getDelay() * 1000.0);
62+
} else {
63+
lambda$autoReconnectTime = -1L;
64+
}
65+
66+
lambda$reconnectButton = ButtonWidget.builder(lambda$getButtonText(), button -> {
67+
lambda$reconnected = true;
68+
AutoReconnect.reconnect(this.parent);
69+
}).width(200).build();
70+
71+
lambda$reconnectButton.active = hasTarget;
72+
this.grid.add(lambda$reconnectButton);
73+
}
74+
75+
@Override
76+
public void render(DrawContext context, int mouseX, int mouseY, float deltaTicks) {
77+
super.render(context, mouseX, mouseY, deltaTicks);
78+
79+
if (lambda$reconnectButton == null || lambda$reconnected) return;
80+
81+
if (AutoReconnect.canAutoReconnect() && lambda$autoReconnectTime > 0) {
82+
long remainingMillis = lambda$autoReconnectTime - System.currentTimeMillis();
83+
if (remainingMillis <= 0) {
84+
lambda$reconnected = true;
85+
AutoReconnect.reconnect(this.parent);
86+
} else {
87+
double remainingSeconds = remainingMillis / 1000.0;
88+
lambda$reconnectButton.setMessage(Text.literal(String.format(Locale.ROOT, "Reconnect (%.1fs)", remainingSeconds)));
89+
}
90+
} else {
91+
lambda$reconnectButton.setMessage(Text.literal("Reconnect"));
92+
}
93+
}
94+
95+
@Override
96+
public void removed() {
97+
super.removed();
98+
lambda$autoReconnectTime = -1L;
99+
lambda$reconnected = true;
100+
}
101+
102+
@Unique
103+
private Text lambda$getButtonText() {
104+
if (AutoReconnect.canAutoReconnect() && lambda$autoReconnectTime > 0) {
105+
long remainingMillis = Math.max(0, lambda$autoReconnectTime - System.currentTimeMillis());
106+
double remainingSeconds = remainingMillis / 1000.0;
107+
return Text.literal(String.format(Locale.ROOT, "Reconnect (%.1fs)", remainingSeconds));
108+
}
109+
return Text.literal("Reconnect");
110+
}
111+
}

‎src/main/java/com/lambda/mixin/world/IntegratedServerLoaderMixin.java‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717

1818
package com.lambda.mixin.world;
1919

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

‎src/main/kotlin/com/lambda/config/settings/complex/KeybindSetting.kt‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import com.lambda.event.Muteable
3636
import com.lambda.event.events.ButtonEvent
3737
import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe
3838
import com.lambda.gui.dsl.ImGuiBuilder
39-
import com.lambda.imgui.ImGui.isMouseClicked
4039
import com.lambda.imgui.flag.ImGuiCol
4140
import com.lambda.imgui.flag.ImGuiHoveredFlags
4241
import com.lambda.imgui.flag.ImGuiMouseButton

‎src/main/kotlin/com/lambda/gui/MenuBar.kt‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import com.lambda.gui.components.QuickSearch
3636
import com.lambda.gui.components.SettingsWidget.buildConfigSettingsContext
3737
import com.lambda.gui.dsl.ImGuiBuilder
3838
import com.lambda.imgui.ImGui
39-
import com.lambda.imgui.ImGui.closeCurrentPopup
4039
import com.lambda.imgui.flag.ImGuiCol
4140
import com.lambda.imgui.flag.ImGuiStyleVar
4241
import com.lambda.imgui.flag.ImGuiWindowFlags

‎src/main/kotlin/com/lambda/gui/dsl/ImGuiBuilder.kt‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
package com.lambda.gui.dsl
2121

2222
import com.lambda.gui.components.ClickGuiLayout
23+
import com.lambda.gui.dsl.ImGuiBuilder.onItemClick
24+
import com.lambda.gui.dsl.ImGuiBuilder.onItemHover
2325
import com.lambda.gui.dsl.ImGuiBuilder.openPopup
2426
import com.lambda.gui.dsl.ImGuiBuilder.text
2527
import com.lambda.imgui.ImDrawList
@@ -108,10 +110,8 @@ import com.lambda.imgui.ImGui.isItemEdited
108110
import com.lambda.imgui.ImGui.isItemFocused
109111
import com.lambda.imgui.ImGui.isItemHovered
110112
import com.lambda.imgui.ImGui.isItemToggledOpen
111-
import com.lambda.imgui.ImGui.isMouseClicked
112113
import com.lambda.imgui.ImGui.isWindowAppearing
113114
import com.lambda.imgui.ImGui.isWindowCollapsed
114-
import com.lambda.imgui.ImGui.isWindowHovered
115115
import com.lambda.imgui.ImGui.plotHistogram
116116
import com.lambda.imgui.ImGui.plotLines
117117
import com.lambda.imgui.ImGui.popFont

‎src/main/kotlin/com/lambda/interaction/material/container/containers/ChestContainer.kt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import com.lambda.interaction.handlers.ContainerHandler
2323
import com.lambda.interaction.material.container.ExternalContainer
2424
import com.lambda.interaction.material.container.MaterialContainer
2525
import com.lambda.task.Task
26-
import com.lambda.task.wrappers.TaskSupplier
2726
import com.lambda.task.tasks.OpenContainerTask
27+
import com.lambda.task.wrappers.TaskSupplier
2828
import com.lambda.task.wrappers.thenAction
2929
import com.lambda.util.extension.containerSlots
3030
import com.lambda.util.text.buildText

‎src/main/kotlin/com/lambda/interaction/material/container/containers/EnderChestContainer.kt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ import com.lambda.interaction.handlers.ContainerHandler.findSlotsWithMaterial
2424
import com.lambda.interaction.material.StackSelection.Companion.select
2525
import com.lambda.interaction.material.container.ExternalContainer
2626
import com.lambda.interaction.material.container.MaterialContainer
27-
import com.lambda.task.wrappers.TaskSupplier
2827
import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock
2928
import com.lambda.task.tasks.OpenContainerTask
3029
import com.lambda.task.tasks.PlaceContainerTask
30+
import com.lambda.task.wrappers.TaskSupplier
3131
import com.lambda.task.wrappers.thenAction
3232
import com.lambda.task.wrappers.thenOrNull
3333
import com.lambda.util.extension.containerSlots

‎src/main/kotlin/com/lambda/interaction/material/container/containers/ShulkerBoxContainer.kt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ import com.lambda.context.SafeContext
2222
import com.lambda.interaction.handlers.ContainerHandler
2323
import com.lambda.interaction.material.container.ExternalContainer
2424
import com.lambda.interaction.material.container.MaterialContainer
25-
import com.lambda.task.wrappers.TaskSupplier
2625
import com.lambda.task.tasks.BuildTask.Companion.breakAndCollectBlock
2726
import com.lambda.task.tasks.OpenContainerTask
2827
import com.lambda.task.tasks.PlaceContainerTask
28+
import com.lambda.task.wrappers.TaskSupplier
2929
import com.lambda.task.wrappers.thenAction
3030
import com.lambda.task.wrappers.thenOrNull
3131
import com.lambda.threading.runSafe

0 commit comments

Comments
 (0)