Skip to content

Commit 6be832b

Browse files
committed
cleaned code and added dependency checker to reduce the possibility of crashes
new sorting algorithm for dependencies as well as disabled mods
1 parent 2711f2b commit 6be832b

18 files changed

Lines changed: 479 additions & 322 deletions

File tree

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ loader_version=0.18.5
1212
loom_version=1.15-SNAPSHOT
1313

1414
# Mod Properties
15-
mod_version=1.5.0
15+
mod_version=1.5.3
1616
maven_group=net.guag.simplemodmanager
1717
archives_base_name=simple-mod-manager
1818

src/main/java/net/guag/simplemodmanager/SimpleModManager.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
package net.guag.simplemodmanager;
22

33
import com.mojang.blaze3d.platform.InputConstants;
4+
45
import net.fabricmc.api.ClientModInitializer;
56
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
67
import net.fabricmc.fabric.api.client.keymapping.v1.KeyMappingHelper;
7-
import net.guag.simplemodmanager.screen.ModManagerScreen;
8-
import net.guag.simplemodmanager.util.ModUtils;
8+
import net.fabricmc.api.ModInitializer;
9+
10+
import net.guag.simplemodmanager.screen.ContentManagerScreen;
11+
import net.guag.simplemodmanager.util.FileUtils;
12+
913
import net.minecraft.client.Minecraft;
1014
import net.minecraft.client.KeyMapping;
1115
import net.minecraft.resources.Identifier;
1216
import org.lwjgl.glfw.GLFW;
1317

14-
import net.fabricmc.api.ModInitializer;
15-
18+
//test seed: -781932279150905825
1619

1720
public class SimpleModManager implements ModInitializer, ClientModInitializer {
1821
private static KeyMapping openUIBinding;
@@ -40,7 +43,7 @@ public void onInitializeClient() {
4043
Minecraft mc = Minecraft.getInstance();
4144
if (mc.screen == null) {
4245
// Pass the client and the hardcoded mod toggles (loaded from file folders)
43-
mc.setScreen(new ModManagerScreen(mc, ModUtils.getModToggles(), ModUtils.getResourceToggles(), ModUtils.getShaderToggles()));
46+
mc.setScreen(new ContentManagerScreen(mc, FileUtils.getModToggles(), FileUtils.getResourceToggles(), FileUtils.getShaderToggles()));
4447
}
4548
}
4649
});
Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,38 @@
11
package net.guag.simplemodmanager.mixin;
22

3-
import net.guag.simplemodmanager.screen.ModManagerScreen;
4-
import net.guag.simplemodmanager.util.ModUtils;
3+
import net.guag.simplemodmanager.screen.ContentManagerScreen;
4+
import net.guag.simplemodmanager.util.FileUtils;
5+
import net.guag.simplemodmanager.widgets.CustomMenuWidget;
56
import net.minecraft.client.Minecraft;
6-
import net.minecraft.client.gui.components.Button;
77
import net.minecraft.client.gui.screens.Screen;
88
import net.minecraft.client.gui.screens.TitleScreen;
99
import net.minecraft.network.chat.Component;
1010
import org.spongepowered.asm.mixin.Mixin;
11+
import org.spongepowered.asm.mixin.Unique;
1112
import org.spongepowered.asm.mixin.injection.At;
1213
import org.spongepowered.asm.mixin.injection.Inject;
13-
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
14+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
15+
1416

1517
@Mixin(TitleScreen.class)
16-
public class LoginWidget extends Screen {
18+
public abstract class LoginWidget extends Screen {
1719

18-
protected LoginWidget(Component title) {
19-
super(title);
20-
}
20+
protected LoginWidget(Component title) { super(title); }
2121

22+
@Unique
23+
CustomMenuWidget iconWidget = new CustomMenuWidget(0, 0, 20, 20, Component.literal(""), _ ->
24+
Minecraft.getInstance().setScreen(
25+
new ContentManagerScreen(Minecraft.getInstance(),
26+
FileUtils.getModToggles(),
27+
FileUtils.getResourceToggles(),
28+
FileUtils.getShaderToggles()
29+
)
30+
));
2231

23-
// @Inject(method = "init", at = @At("RETURN"))
24-
// private void addOpenGUIButton(int y, int spacingY, CallbackInfo ci) {
25-
// // 'this' here refers to the TitleScreen instance at runtime
26-
// TitleScreen self = (TitleScreen)(Object)this;
27-
// addWidget(
28-
// Button.builder(
29-
// Component.translatable("button.SimpleModManager.opengui"),
30-
// button -> Minecraft.getInstance().setScreen(
31-
// new ModManagerScreen(Minecraft.getInstance(),
32-
// ModUtils.getModToggles(),
33-
// ModUtils.getResourceToggles(),
34-
// ModUtils.getShaderToggles())))
35-
// .bounds(self.width / 2 - 100 + 205, y, 20, 20)
36-
// .build()
37-
// );
38-
// }
39-
}
32+
@Inject(method = "createNormalMenuOptions", at = @At("RETURN"))
33+
private void addOpenGUIButton(int topPos, final int spacing, CallbackInfoReturnable<Void> cir){
34+
addRenderableWidget(iconWidget);
35+
iconWidget.setX(this.width / 2 + 104);
36+
iconWidget.setY(topPos);
37+
}
38+
}
Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,39 @@
11
package net.guag.simplemodmanager.mixin;
22

3-
import net.guag.simplemodmanager.screen.ModManagerScreen;
4-
import net.guag.simplemodmanager.util.ModUtils;
3+
import net.guag.simplemodmanager.screen.ContentManagerScreen;
4+
import net.guag.simplemodmanager.util.FileUtils;
5+
import net.guag.simplemodmanager.widgets.CustomMenuWidget;
56
import net.minecraft.client.Minecraft;
6-
import net.minecraft.client.gui.components.Button;
7+
import net.minecraft.client.gui.screens.PauseScreen;
78
import net.minecraft.client.gui.screens.Screen;
8-
import net.minecraft.client.gui.screens.TitleScreen;
99
import net.minecraft.network.chat.Component;
1010
import org.spongepowered.asm.mixin.Mixin;
11+
import org.spongepowered.asm.mixin.Unique;
1112
import org.spongepowered.asm.mixin.injection.At;
1213
import org.spongepowered.asm.mixin.injection.Inject;
1314
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
15+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
1416

15-
@Mixin(TitleScreen.class)
16-
public class PauseWidget extends Screen {
1717

18-
protected PauseWidget(Component title) {
19-
super(title);
20-
}
21-
//
22-
//
23-
// @Inject(method = "init", at = @At("RETURN"))
24-
// private void addOpenGUIButton(int y, int spacingY, CallbackInfo ci) {
25-
// // 'this' here refers to the TitleScreen instance at runtime
26-
// TitleScreen self = (TitleScreen)(Object)this;
27-
// addWidget(
28-
// Button.builder(
29-
// Component.translatable("button.SimpleModManager.opengui"),
30-
// button -> Minecraft.getInstance().setScreen(
31-
// new ModManagerScreen(Minecraft.getInstance(),
32-
// ModUtils.getModToggles(),
33-
// ModUtils.getResourceToggles(),
34-
// ModUtils.getShaderToggles())))
35-
// .bounds(self.width / 2 - 100 + 205, y, 20, 20)
36-
// .build()
37-
// );
18+
@Mixin(PauseScreen.class)
19+
public abstract class PauseWidget extends Screen {
20+
21+
protected PauseWidget(Component title) { super(title); }
22+
23+
@Unique
24+
CustomMenuWidget iconWidget = new CustomMenuWidget(0, 0, 20, 20, Component.literal(""), _ ->
25+
Minecraft.getInstance().setScreen(
26+
new ContentManagerScreen(Minecraft.getInstance(),
27+
FileUtils.getModToggles(),
28+
FileUtils.getResourceToggles(),
29+
FileUtils.getShaderToggles()
30+
)
31+
));
32+
33+
// @Inject(method = "createPauseMenu", at = @At("RETURN"))
34+
// private void addOpenGUIButton(CallbackInfo ci){
35+
// addRenderableWidget(iconWidget);
36+
// iconWidget.setX(this.width / 2 + 103);
37+
// iconWidget.setY(this.height / 2);
3838
// }
39-
}
39+
}

src/main/java/net/guag/simplemodmanager/screen/ModManagerScreen.java renamed to src/main/java/net/guag/simplemodmanager/screen/ContentManagerScreen.java

Lines changed: 56 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
package net.guag.simplemodmanager.screen;
22

33
import net.guag.simplemodmanager.util.DrawingUtils;
4-
import net.guag.simplemodmanager.util.ResourceUtils;
54
import net.guag.simplemodmanager.widgets.CustomButtonWidget;
65
import net.guag.simplemodmanager.widgets.CustomTextWidget;
6+
77
import net.minecraft.client.Minecraft;
88
import net.minecraft.client.gui.GuiGraphicsExtractor;
9+
import net.minecraft.client.gui.components.Tooltip;
910
import net.minecraft.client.gui.screens.Screen;
1011
import net.minecraft.client.gui.components.Button;
1112
import net.minecraft.client.gui.components.EditBox;
1213
import net.minecraft.network.chat.Component;
13-
import org.jetbrains.annotations.NotNull;
1414

15+
import org.jetbrains.annotations.NotNull;
1516

1617
import java.util.*;
1718

1819

19-
public class ModManagerScreen extends Screen{
20+
public class ContentManagerScreen extends Screen{
2021

2122
private final Minecraft client;
22-
private final List<ModToggle> modToggles;
23-
private final List<ModToggle> resourceToggles;
24-
private final List<ModToggle> shaderToggles;
23+
private final List<FileToggle> modToggles;
24+
private final List<FileToggle> resourceToggles;
25+
private final List<FileToggle> shaderToggles;
2526

2627
DrawingUtils drawUtil = new DrawingUtils();
2728

@@ -50,8 +51,9 @@ public class ModManagerScreen extends Screen{
5051

5152
private final List<Button> headerButtons = new ArrayList<>();
5253

54+
private static final ArrayList<String> dependencies = new ArrayList<>();
5355

54-
public ModManagerScreen(Minecraft client, List<ModToggle> modToggles, List<ModToggle> resourceToggles, List<ModToggle> shaderToggles) {
56+
public ContentManagerScreen(Minecraft client, List<FileToggle> modToggles, List<FileToggle> resourceToggles, List<FileToggle> shaderToggles) {
5557
super(Component.literal("Simple Mod Manager"));
5658
this.client = client;
5759
this.modToggles = modToggles;
@@ -61,7 +63,6 @@ public ModManagerScreen(Minecraft client, List<ModToggle> modToggles, List<ModTo
6163

6264
@Override
6365
protected void init() {
64-
ResourceUtils resourceUtil = new ResourceUtils();
6566
this.modToggleButtons.clear();
6667
this.modResetButtons.clear();
6768
this.modMetadataButtons.clear();
@@ -91,7 +92,7 @@ protected void init() {
9192
// Tab buttons
9293
int tabY = 42;
9394
int tabSpacing = 4;
94-
int tabW = (this.width - 20 - tabSpacing * 2) / 3; // 20 = 10px from each edge
95+
int tabW = (this.width - 20 - tabSpacing * 2) / 3; // 20 = 10 px from each edge
9596
int tabStartX = 10;
9697
Button modsTab = CustomButtonWidget.builder(Component.literal("Mods"), _ -> { activeTab = "mods"; updateScroll(); })
9798
.bounds(tabStartX, tabY, tabW, 18).build();
@@ -107,23 +108,51 @@ protected void init() {
107108
addWidget(resourcesTab);
108109
addWidget(shadersTab);
109110

110-
ModToggle.initializeDefaultDisabledMods();
111+
FileToggle.initializeDefaultDisabledMods();
111112

112113
int index = 0;
113-
for (ModToggle toggle : modToggles) {
114-
Button toggleFunc = Button.builder(Component.literal(toggle.getButtonText().getString()), button -> {
115-
toggle.toggled();
116-
button.setMessage(Component.literal(toggle.getButtonText().getString()));
114+
115+
//get dependencies
116+
for (FileToggle toggle : modToggles) {
117+
for (String dependency : toggle.getDependencies()) {
118+
if (!dependencies.contains(dependency)) dependencies.add(dependency);
119+
}
120+
}
121+
122+
//sort putting non-toggleable mods last
123+
modToggles.sort((a, b) -> {
124+
boolean aDep = dependencies.contains(a.getModId());
125+
boolean bDep = dependencies.contains(b.getModId());
126+
if (aDep != bDep) return Boolean.compare(aDep, bDep); // dependencies last
127+
return Boolean.compare(!a.isEnabled(), !b.isEnabled()); // disabled last within each group
128+
});
129+
130+
for (FileToggle toggle : modToggles) {
131+
Button toggleFunc = Button.builder(Component.literal(toggle.getButtonText().getString()), button -> {
132+
if (!dependencies.contains(toggle.getModId())){
133+
toggle.toggled();
134+
button.setMessage(Component.literal(toggle.getButtonText().getString()));
135+
} else {
136+
button.setTooltip(Tooltip.create(Component.literal("§7Dependency")));
137+
}
117138
}).bounds(0, 0, 60, btnHeight).build();
139+
140+
toggleFunc.active = !dependencies.contains(toggle.getModId()); //set toggle state depending on if it's a dependency
141+
// System.out.println(toggle.getModId() + (dependencies.contains(toggle.getModId()) ? " IS dependency " : " is NOT dependency"));
142+
// System.out.println(dependencies);
143+
118144
addWidget(toggleFunc);
119145
modToggleButtons.add(toggleFunc);
120146

121147
// capture before lambda
122148
Button resetFunc = Button.builder(Component.literal("Reset"), _ -> {
123-
toggle.resetToDefault();
124-
toggleFunc.setMessage(Component.literal(toggle.getButtonText().getString()));
149+
if (!dependencies.contains(toggle.getModId())){
150+
toggle.resetToDefault();
151+
toggleFunc.setMessage(Component.literal(toggle.getButtonText().getString()));
152+
}
125153
}).bounds(0, 0, 50, btnHeight).build();
126-
addWidget(resetFunc); // ← add this
154+
resetFunc.active = !dependencies.contains(toggle.getModId());
155+
addWidget(resetFunc);
127156
modResetButtons.add(resetFunc);
128157

129158
Button metadataFunc = Button.builder(
@@ -137,7 +166,7 @@ protected void init() {
137166
}
138167

139168
index = 0;
140-
for (ModToggle toggle : resourceToggles) {
169+
for (FileToggle toggle : resourceToggles) {
141170
Button resourceMetadataFunc = Button.builder(
142171
Component.literal(resourceToggles.get(index).getFile().getName()), _ -> {}
143172
).bounds(0, 0, 0, btnHeight).build();
@@ -147,7 +176,6 @@ protected void init() {
147176

148177
Button resourceToggleFunc = Button.builder(Component.literal(toggle.getButtonText().getString()), button -> {
149178
toggle.toggled();
150-
resourceUtil.toggleResourcePack(toggle.getFile().getName(), toggle.isEnabled());
151179
button.setMessage(Component.literal(toggle.getButtonText().getString()));
152180
}).bounds(0, 0, 60, btnHeight).build();
153181
addWidget(resourceToggleFunc);
@@ -156,7 +184,7 @@ protected void init() {
156184
}
157185

158186
index = 0;
159-
for (ModToggle toggle : shaderToggles) {
187+
for (FileToggle toggle : shaderToggles) {
160188
Button shaderMetadataFunc = Button.builder(
161189
Component.literal(shaderToggles.get(index).getFile().getName()), _ -> {}
162190
).bounds(0, 0, 0, btnHeight).build();
@@ -166,22 +194,18 @@ protected void init() {
166194

167195
Button shaderToggleFunc = Button.builder(Component.literal(toggle.getButtonText().getString()), button -> {
168196
toggle.toggled();
169-
resourceUtil.toggleShaderPack(toggle.getFile().getName(), toggle.isEnabled());
170197
button.setMessage(Component.literal(toggle.getButtonText().getString()));
171198
}).bounds(0, 0, 60, btnHeight).build();
172199
addWidget(shaderToggleFunc);
173200
shaderToggleButtons.add(shaderToggleFunc);
174201
index++;
175202
}
176203

177-
Button resourceFunc = Button.builder(Component.literal("Refresh Resources"), _ -> {
178-
Minecraft.getInstance().reloadResourcePacks();
179-
client.setScreen(null);
180-
}).bounds(0, 0, 160, btnHeight).build();
181-
addWidget(resourceFunc);
182-
183204
Button applyFunc = Button.builder(Component.literal("Apply Changes"), _ -> {
184-
for (ModToggle toggle : modToggles) toggle.applyChange();
205+
for (FileToggle toggle : modToggles) toggle.applyChange("mod");
206+
for (FileToggle toggle : resourceToggles) toggle.applyChange("resourcepack"); //FileUtils.toggleResourcePack(toggle.getFile().getName(), toggle.isEnabled());
207+
for (FileToggle toggle : shaderToggles) toggle.applyChange("shaderpack"); //FileUtils.toggleShaderPack(toggle.getFile().getName(), toggle.isEnabled());
208+
185209
client.setScreen(null);
186210
Minecraft.getInstance().reloadResourcePacks();
187211
}).bounds(0, 0, 120, btnHeight).build();
@@ -230,7 +254,7 @@ public void extractRenderState(@NotNull GuiGraphicsExtractor context, int mouseX
230254
int toggleX = this.width - 190;
231255
int resetX = this.width - 120;
232256

233-
//button container fill first so buttons are on top
257+
//button container fills first so buttons are on top
234258
context.fill(10, listTop, this.width - 10, listBottom, 0x88111111);
235259

236260

@@ -239,7 +263,7 @@ public void extractRenderState(@NotNull GuiGraphicsExtractor context, int mouseX
239263
switch (activeTab) {
240264
case "mods" -> {
241265
for (int i = 0; i < modToggles.size(); i++) {
242-
ModToggle toggle = modToggles.get(i);
266+
FileToggle toggle = modToggles.get(i);
243267

244268
// always increment y and skip if filtered
245269
if (!toggle.getDisplayName().toLowerCase().contains(searchQuery)) {
@@ -282,7 +306,7 @@ public void extractRenderState(@NotNull GuiGraphicsExtractor context, int mouseX
282306
}
283307
case "resourcepacks" -> {
284308
for (int i = 0; i < resourceToggles.size(); i++) {
285-
ModToggle toggle = resourceToggles.get(i);
309+
FileToggle toggle = resourceToggles.get(i);
286310

287311
// always increment y and skip if filtered
288312
if (!toggle.getDisplayName().toLowerCase().contains(searchQuery)) {
@@ -319,7 +343,7 @@ public void extractRenderState(@NotNull GuiGraphicsExtractor context, int mouseX
319343
}
320344
case "shaderpacks" -> {
321345
for (int i = 0; i < shaderToggles.size(); i++) {
322-
ModToggle toggle = shaderToggles.get(i);
346+
FileToggle toggle = shaderToggles.get(i);
323347

324348
// always increment y and skip if filtered
325349
if (!toggle.getDisplayName().toLowerCase().contains(searchQuery)) {
@@ -421,5 +445,4 @@ private void updateVisibleButtonsBasedOnSearch() {
421445
shaderMetadataButtons.get(i).visible = show;
422446
}
423447
}
424-
425448
}

0 commit comments

Comments
 (0)