Skip to content
This repository was archived by the owner on Dec 30, 2022. It is now read-only.

Commit 473371a

Browse files
authored
Merge pull request #89 from DeathsGun/features/77_blacklist_mods
Allow updates to be blacklisted
2 parents 5323df3 + e9b15cd commit 473371a

File tree

10 files changed

+159
-16
lines changed

10 files changed

+159
-16
lines changed

src/main/java/xyz/deathsgun/modmanager/mixin/ModsScreenMixin.java

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818

1919
import com.terraformersmc.modmenu.gui.ModsScreen;
2020
import com.terraformersmc.modmenu.gui.widget.ModMenuTexturedButtonWidget;
21+
import com.terraformersmc.modmenu.gui.widget.entries.ModListEntry;
2122
import net.minecraft.client.MinecraftClient;
2223
import net.minecraft.client.gui.screen.Screen;
24+
import net.minecraft.text.LiteralText;
2325
import net.minecraft.text.Text;
2426
import net.minecraft.text.TranslatableText;
2527
import net.minecraft.util.Identifier;
@@ -28,14 +30,31 @@
2830
import org.spongepowered.asm.mixin.injection.At;
2931
import org.spongepowered.asm.mixin.injection.Inject;
3032
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
33+
import xyz.deathsgun.modmanager.ModManager;
34+
import xyz.deathsgun.modmanager.config.Config;
3135
import xyz.deathsgun.modmanager.gui.ModsOverviewScreen;
36+
import xyz.deathsgun.modmanager.gui.widget.TexturedButton;
37+
38+
import java.util.Map;
3239

3340
@Mixin(ModsScreen.class)
34-
public class ModsScreenMixin extends Screen {
41+
public abstract class ModsScreenMixin extends Screen {
3542

3643
private static final Identifier MODMANAGER_BUTTON_LOCATION = new Identifier("modmanager", "textures/gui/install_button.png");
44+
private static final Identifier MODMANAGER_HIDE_BUTTON = new Identifier("modmanager", "textures/gui/hide_button.png");
45+
private static final Identifier MODMANAGER_SHOW_BUTTON = new Identifier("modmanager", "textures/gui/show_button.png");
3746
@Shadow
3847
private int paneWidth;
48+
@Shadow
49+
private int paneY;
50+
51+
@Shadow
52+
private ModListEntry selected;
53+
54+
@Shadow
55+
public abstract Map<String, Boolean> getModHasConfigScreen();
56+
57+
private TexturedButton hideButton;
3958

4059
protected ModsScreenMixin(Text title) {
4160
super(title);
@@ -47,6 +66,42 @@ public void onInit(CallbackInfo ci) {
4766
this.addDrawableChild(new ModMenuTexturedButtonWidget(this.paneWidth / 2 + searchBoxWidth / 2 + 14,
4867
22, 20, 20, 0, 0, MODMANAGER_BUTTON_LOCATION, 32, 64, button -> {
4968
MinecraftClient.getInstance().setScreen(new ModsOverviewScreen(this));
50-
}, new TranslatableText("modmanager.button.open")));
69+
}, LiteralText.EMPTY, (button, matrices, mouseX, mouseY) -> {
70+
if (!button.isHovered()) {
71+
return;
72+
}
73+
this.renderTooltip(matrices, new TranslatableText("modmanager.button.open"), mouseX, mouseY);
74+
}));
75+
this.hideButton = this.addDrawableChild(new TexturedButton(width - 24 - 22, paneY, 20, 20, 0,
76+
0, MODMANAGER_HIDE_BUTTON, 32, 64, button -> {
77+
if (ModManager.modManager.config.getHidden().contains(selected.getMod().getId())) {
78+
ModManager.modManager.config.getHidden().remove(selected.getMod().getId());
79+
} else {
80+
ModManager.modManager.config.getHidden().add(selected.getMod().getId());
81+
}
82+
Config.Companion.saveConfig(ModManager.modManager.config);
83+
}, ((button, matrices, mouseX, mouseY) -> {
84+
if (!hideButton.isJustHovered() || !button.isHovered()) {
85+
return;
86+
}
87+
TranslatableText text = new TranslatableText("modmanager.button.hide");
88+
if (ModManager.modManager.config.getHidden().contains(selected.getMod().getId())) {
89+
text = new TranslatableText("modmanager.button.show");
90+
}
91+
this.renderTooltip(matrices, text, mouseX, mouseY);
92+
})));
5193
}
94+
95+
@Inject(method = "tick", at = @At("HEAD"))
96+
public void onTick(CallbackInfo ci) {
97+
this.hideButton.visible = ModManager.modManager.getUpdate().getUpdates()
98+
.stream().anyMatch(it -> it.getFabricId().equalsIgnoreCase(selected.mod.getId()));
99+
if (ModManager.modManager.config.getHidden().contains(selected.getMod().getId())) {
100+
this.hideButton.setImage(MODMANAGER_SHOW_BUTTON);
101+
} else {
102+
this.hideButton.setImage(MODMANAGER_HIDE_BUTTON);
103+
}
104+
this.hideButton.x = getModHasConfigScreen().getOrDefault(selected.getMod().getId(), false) ? width - 24 - 22 : width - 24;
105+
}
106+
52107
}

src/main/java/xyz/deathsgun/modmanager/mixin/TitleScreenMixin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import xyz.deathsgun.modmanager.ModManager;
3030
import xyz.deathsgun.modmanager.update.Update;
3131

32-
import java.util.ArrayList;
32+
import java.util.List;
3333
import java.util.Objects;
3434

3535
@Mixin(TitleScreen.class)
@@ -45,7 +45,7 @@ public void onRender(MatrixStack matrices, int mouseX, int mouseY, float delta,
4545
return;
4646
}
4747
ModManager.shownUpdateNotification = true;
48-
ArrayList<Update> updates = ModManager.modManager.getUpdate().getUpdates();
48+
List<Update> updates = ModManager.modManager.getUpdate().getWhitelistedUpdates();
4949
if (updates.isEmpty()) {
5050
return;
5151
}

src/main/kotlin/xyz/deathsgun/modmanager/config/Config.kt

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,31 +30,38 @@ import java.nio.file.Files
3030

3131
@Serializable
3232
data class Config(
33-
var defaultProvider: String,
34-
var updateChannel: UpdateChannel
33+
var defaultProvider: String = "modrinth",
34+
var updateChannel: UpdateChannel = UpdateChannel.ALL,
35+
var hidden: ArrayList<String> = ArrayList()
3536
) {
3637

3738
companion object {
39+
40+
private val json = Json {
41+
prettyPrint = true
42+
encodeDefaults = true
43+
}
44+
3845
@OptIn(ExperimentalSerializationApi::class)
3946
fun loadConfig(): Config {
4047
return try {
4148
val file = FabricLoader.getInstance().configDir.resolve("modmanager.json")
4249
Files.createDirectories(file.parent)
4350
val data = Files.readString(file, Charset.forName("UTF-8"))
44-
Json.decodeFromString(data)
51+
json.decodeFromString(data)
4552
} catch (e: Exception) {
4653
if (e !is NoSuchFileException) {
4754
e.printStackTrace()
4855
}
49-
saveConfig(Config("modrinth", UpdateChannel.ALL))
56+
saveConfig(Config())
5057
}
5158
}
5259

5360
@OptIn(ExperimentalSerializationApi::class)
5461
fun saveConfig(config: Config): Config {
5562
try {
5663
val file = FabricLoader.getInstance().configDir.resolve("modmanager.json")
57-
val data = Json.encodeToString(config)
64+
val data = json.encodeToString(config)
5865
Files.writeString(file, data, Charset.forName("UTF-8"))
5966
} catch (ignored: Exception) {
6067
}

src/main/kotlin/xyz/deathsgun/modmanager/gui/ModsOverviewScreen.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ class ModsOverviewScreen(private val previousScreen: Screen) : Screen(Translatab
130130
}
131131
is CategoriesResult.Success -> {
132132
categoryList.clear()
133-
if (ModManager.modManager.update.updates.isNotEmpty()) {
133+
if (ModManager.modManager.update.getWhitelistedUpdates().isNotEmpty()) {
134134
categoryList.add(Category("updatable", TranslatableText("modmanager.category.updatable")))
135135
}
136136
categoryList.addCategories(result.categories)
@@ -186,7 +186,7 @@ class ModsOverviewScreen(private val previousScreen: Screen) : Screen(Translatab
186186
val provider = ModManager.modManager.getSelectedProvider() ?: return
187187
if (selectedCategories.any { it.id == "updatable" }) {
188188
modList.clear()
189-
ModManager.modManager.update.updates.forEach {
189+
ModManager.modManager.update.getWhitelistedUpdates().forEach {
190190
modList.add(it.mod)
191191
}
192192
return
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright 2021 DeathsGun
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package xyz.deathsgun.modmanager.gui.widget
18+
19+
import com.mojang.blaze3d.systems.RenderSystem
20+
import com.terraformersmc.modmenu.gui.widget.ModMenuTexturedButtonWidget
21+
import net.minecraft.client.util.math.MatrixStack
22+
import net.minecraft.text.LiteralText
23+
import net.minecraft.util.Identifier
24+
25+
class TexturedButton(
26+
x: Int,
27+
y: Int,
28+
width: Int,
29+
height: Int,
30+
private val u: Int,
31+
private val v: Int,
32+
texture: Identifier,
33+
private val uWidth: Int,
34+
private val vHeight: Int,
35+
onPress: PressAction?,
36+
tooltipSupplier: TooltipSupplier
37+
) : ModMenuTexturedButtonWidget(
38+
x,
39+
y,
40+
width,
41+
height,
42+
u,
43+
v,
44+
texture,
45+
uWidth,
46+
vHeight,
47+
onPress,
48+
LiteralText.EMPTY,
49+
tooltipSupplier
50+
) {
51+
52+
var image: Identifier = texture
53+
54+
override fun renderButton(matrices: MatrixStack, mouseX: Int, mouseY: Int, delta: Float) {
55+
RenderSystem.setShaderColor(1f, 1f, 1f, 1f)
56+
RenderSystem.setShaderTexture(0, image)
57+
RenderSystem.disableDepthTest()
58+
var adjustedV = v
59+
if (!active) {
60+
adjustedV += height * 2
61+
} else if (this.isHovered) {
62+
adjustedV += height
63+
}
64+
drawTexture(
65+
matrices,
66+
x, y, u.toFloat(), adjustedV.toFloat(), width, height, uWidth, vHeight
67+
)
68+
RenderSystem.enableDepthTest()
69+
if (this.isHovered) {
70+
renderTooltip(matrices, mouseX, mouseY)
71+
}
72+
}
73+
74+
}

src/main/kotlin/xyz/deathsgun/modmanager/update/UpdateManager.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ class UpdateManager {
220220
fun getUpdateForMod(mod: Mod): Update? {
221221
return this.updates.find { it.mod.id == mod.id || it.fabricId == mod.slug }
222222
}
223+
224+
fun getWhitelistedUpdates(): List<Update> {
225+
return this.updates.filter { !ModManager.modManager.config.hidden.contains(it.fabricId) }
226+
}
223227
//endregion
224228

225229
fun installMod(mod: Mod): ModInstallResult {

src/main/resources/assets/modmanager/lang/en_us.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
"modmanager.button.defaultProvider": "Default provider",
1010
"modmanager.button.updateChannel": "Update channel",
1111
"modmanager.button.save": "Save",
12+
"modmanager.button.hide": "Hide updates",
13+
"modmanager.button.show": "Show updates",
14+
"modmanager.button.open": "Open ModManager",
1215
"modmanager.categories": "Categories",
1316
"modmanager.category.updatable": "Updatable mods",
1417
"modmanager.category.technology": "Technology",
Loading
Loading

src/main/resources/fabric.mod.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@
3535
"modmanager.mixins.json"
3636
],
3737
"depends": {
38-
"fabricloader": ">=0.12",
39-
"modmenu": ">=${modmenu_version}",
40-
"fabric-language-kotlin": ">=${fabric_kotlin_version}",
41-
"minecraft": "1.17.x",
42-
"java": ">=16"
38+
"fabricloader": "~0.12",
39+
"modmenu": "~${modmenu_version}",
40+
"fabric-language-kotlin": ">=${fabric_kotlin_version}",
41+
"minecraft": "1.17.x",
42+
"java": ">=16"
4343
}
4444
}

0 commit comments

Comments
 (0)