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

Commit 5bcc55d

Browse files
committed
Merge branch '1.17' into 1.18
# Conflicts: # src/main/kotlin/xyz/deathsgun/modmanager/update/UpdateManager.kt
2 parents 42367b3 + 6d7e7e0 commit 5bcc55d

File tree

19 files changed

+404
-95
lines changed

19 files changed

+404
-95
lines changed

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,18 @@ public void onInit(CallbackInfo ci) {
7474
}));
7575
this.hideButton = this.addDrawableChild(new TexturedButton(width - 24 - 22, paneY, 20, 20, 0,
7676
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());
77+
if (ModManager.modManager.getConfig().getHidden().contains(selected.getMod().getId())) {
78+
ModManager.modManager.getConfig().getHidden().remove(selected.getMod().getId());
7979
} else {
80-
ModManager.modManager.config.getHidden().add(selected.getMod().getId());
80+
ModManager.modManager.getConfig().getHidden().add(selected.getMod().getId());
8181
}
82-
Config.Companion.saveConfig(ModManager.modManager.config);
82+
Config.Companion.saveConfig(ModManager.modManager.getConfig());
8383
}, ((button, matrices, mouseX, mouseY) -> {
8484
if (!hideButton.isJustHovered() || !button.isHovered()) {
8585
return;
8686
}
8787
TranslatableText text = new TranslatableText("modmanager.button.hide");
88-
if (ModManager.modManager.config.getHidden().contains(selected.getMod().getId())) {
88+
if (ModManager.modManager.getConfig().getHidden().contains(selected.getMod().getId())) {
8989
text = new TranslatableText("modmanager.button.show");
9090
}
9191
this.renderTooltip(matrices, text, mouseX, mouseY);
@@ -96,7 +96,7 @@ public void onInit(CallbackInfo ci) {
9696
public void onTick(CallbackInfo ci) {
9797
this.hideButton.visible = ModManager.modManager.getUpdate().getUpdates()
9898
.stream().anyMatch(it -> it.getFabricId().equalsIgnoreCase(selected.mod.getId()));
99-
if (ModManager.modManager.config.getHidden().contains(selected.getMod().getId())) {
99+
if (ModManager.modManager.getConfig().getHidden().contains(selected.getMod().getId())) {
100100
this.hideButton.setImage(MODMANAGER_SHOW_BUTTON);
101101
} else {
102102
this.hideButton.setImage(MODMANAGER_HIDE_BUTTON);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ protected TitleScreenMixin(Text title) {
4141

4242
@Inject(at = @At("TAIL"), method = "render")
4343
public void onRender(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) {
44-
if (ModManager.shownUpdateNotification) {
44+
if (ModManager.shownUpdateNotification && ModManager.modManager.getUpdate().getFinishedUpdateCheck()) {
4545
return;
4646
}
4747
ModManager.shownUpdateNotification = true;

src/main/kotlin/xyz/deathsgun/modmanager/ModManager.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,19 @@ import xyz.deathsgun.modmanager.update.UpdateManager
3434
class ModManager : ClientModInitializer {
3535

3636
private val states = ArrayList<SavedState>()
37-
lateinit var config: Config
37+
var config: Config = Config.loadConfig()
3838
var changed: Boolean = false
3939
val update: UpdateManager = UpdateManager()
4040
val icons: IconCache = IconCache()
4141
val provider: HashMap<String, IModProvider> = HashMap()
4242
val updateProvider: HashMap<String, IModUpdateProvider> = HashMap()
4343

44+
init {
45+
val modrinth = Modrinth()
46+
provider[modrinth.getName().lowercase()] = modrinth
47+
updateProvider[modrinth.getName().lowercase()] = modrinth
48+
}
49+
4450
companion object {
4551
@JvmField
4652
var shownUpdateNotification: Boolean = false
@@ -67,13 +73,7 @@ class ModManager : ClientModInitializer {
6773

6874
@OptIn(DelicateCoroutinesApi::class)
6975
override fun onInitializeClient() {
70-
modManager = this
71-
config = Config.loadConfig()
72-
val modrinth = Modrinth()
73-
provider[modrinth.getName().lowercase()] = modrinth
74-
updateProvider[modrinth.getName().lowercase()] = modrinth
7576
GlobalScope.launch {
76-
update.checkUpdates()
7777
icons.cleanupCache()
7878
}
7979
}

src/main/kotlin/xyz/deathsgun/modmanager/PreLaunchHook.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
package xyz.deathsgun.modmanager
1818

19+
import kotlinx.coroutines.DelicateCoroutinesApi
20+
import kotlinx.coroutines.GlobalScope
21+
import kotlinx.coroutines.launch
1922
import kotlinx.serialization.ExperimentalSerializationApi
2023
import kotlinx.serialization.decodeFromString
2124
import kotlinx.serialization.json.Json
@@ -30,7 +33,12 @@ class PreLaunchHook : PreLaunchEntrypoint {
3033

3134
private val logger = LogManager.getLogger("ModManager")
3235

36+
@OptIn(DelicateCoroutinesApi::class)
3337
override fun onPreLaunch() {
38+
GlobalScope.launch {
39+
ModManager.modManager = ModManager()
40+
ModManager.modManager.update.checkUpdates()
41+
}
3442
val filesToDelete = try {
3543
loadFiles()
3644
} catch (e: Exception) {

src/main/kotlin/xyz/deathsgun/modmanager/api/gui/list/ListWidget.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ abstract class ListWidget<E : ListWidget.Entry<E>>(
4848
private var selectedId: String? = null
4949
private var scrolling = false
5050

51-
abstract fun init()
52-
5351
override fun isFocused(): Boolean {
5452
return parent.getFocused() == this
5553
}
@@ -144,7 +142,7 @@ abstract class ListWidget<E : ListWidget.Entry<E>>(
144142
return selectedId == entry.id
145143
}
146144

147-
fun getEntryAtPos(x: Int, y: Int): Entry<E>? {
145+
private fun getEntryAtPos(x: Int, y: Int): Entry<E>? {
148146
val int5 = MathHelper.floor(y - top.toDouble()) - headerHeight + scrollAmount.toInt() - 4
149147
val index = int5 / itemHeight
150148
return if (x < this.scrollbarPositionX.toDouble() && x >= rowLeft.toDouble() && x <= (rowLeft + rowWidth).toDouble() && index >= 0
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package xyz.deathsgun.modmanager.api.http
2+
3+
import java.io.ByteArrayInputStream
4+
import java.io.InputStream
5+
import java.net.HttpURLConnection
6+
import java.net.URI
7+
import java.net.URL
8+
import java.nio.file.Files
9+
import java.nio.file.Path
10+
import kotlin.math.min
11+
12+
object HttpClient {
13+
14+
fun get(url: String): ByteArray {
15+
return get(URI.create(url))
16+
}
17+
18+
fun get(uri: URI): ByteArray {
19+
val connection = uri.toURL().openConnection() as HttpURLConnection
20+
connection.readTimeout = 10000
21+
connection.requestMethod = "GET"
22+
connection.connect()
23+
if (connection.responseCode != 200) {
24+
connection.disconnect()
25+
throw InvalidStatusCodeException(connection.responseCode)
26+
}
27+
val content = connection.inputStream.readBytes()
28+
connection.disconnect()
29+
return content
30+
}
31+
32+
fun getInputStream(url: String): InputStream {
33+
return getInputStream(URI.create(url))
34+
}
35+
36+
private fun getInputStream(uri: URI): InputStream {
37+
return ByteArrayInputStream(get(uri))
38+
}
39+
40+
fun download(url: String, path: Path, listener: ((Double) -> Unit)? = null) {
41+
val output = Files.newOutputStream(path)
42+
val connection = URL(url).openConnection() as HttpURLConnection
43+
connection.readTimeout = 10000
44+
connection.requestMethod = "GET"
45+
connection.connect()
46+
if (connection.responseCode != 200) {
47+
connection.disconnect()
48+
throw InvalidStatusCodeException(connection.responseCode)
49+
}
50+
val size = connection.contentLength
51+
var downloaded = 0
52+
while (true) {
53+
val buffer = ByteArray(min(1024, size - downloaded))
54+
val read = connection.inputStream.read(buffer)
55+
if (read == -1) {
56+
break
57+
}
58+
output.write(buffer, 0, read)
59+
downloaded += read
60+
listener?.invoke((downloaded / size).toDouble())
61+
}
62+
connection.disconnect()
63+
output.flush()
64+
output.close()
65+
}
66+
67+
class InvalidStatusCodeException(val statusCode: Int) : Exception("Received invalid status code: $statusCode")
68+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ import xyz.deathsgun.modmanager.gui.widget.DescriptionWidget
3030
import xyz.deathsgun.modmanager.update.Update
3131

3232

33-
class ModUpdateInfoScreen(private val previousScreen: Screen, private val update: Update) :
34-
Screen(TranslatableText("modmanager.screen.update")), IListScreen {
33+
class ModUpdateInfoScreen(private val previousScreen: Screen, private val update: Update) : Screen(LiteralText.EMPTY),
34+
IListScreen {
3535

3636
private lateinit var descriptionWidget: DescriptionWidget
3737
private lateinit var updateButtonWidget: ButtonWidget

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import net.minecraft.client.gui.widget.ButtonWidget
2727
import net.minecraft.client.gui.widget.CyclingButtonWidget
2828
import net.minecraft.client.gui.widget.TextFieldWidget
2929
import net.minecraft.client.util.math.MatrixStack
30+
import net.minecraft.text.LiteralText
3031
import net.minecraft.text.TranslatableText
3132
import org.lwjgl.glfw.GLFW
3233
import xyz.deathsgun.modmanager.ModManager
@@ -41,8 +42,7 @@ import xyz.deathsgun.modmanager.gui.widget.ModListEntry
4142
import xyz.deathsgun.modmanager.gui.widget.ModListWidget
4243
import kotlin.math.min
4344

44-
class ModsOverviewScreen(private val previousScreen: Screen) : Screen(TranslatableText("modmanager.title.overview")),
45-
IListScreen {
45+
class ModsOverviewScreen(private val previousScreen: Screen) : Screen(LiteralText.EMPTY), IListScreen {
4646

4747
private var query: String = ""
4848
private var selectedMod: ModListEntry? = null
@@ -58,6 +58,7 @@ class ModsOverviewScreen(private val previousScreen: Screen) : Screen(Translatab
5858
private lateinit var categoryList: CategoryListWidget
5959
private lateinit var nextPage: ButtonWidget
6060
private lateinit var previousPage: ButtonWidget
61+
private lateinit var updateAll: ButtonWidget
6162

6263
@OptIn(DelicateCoroutinesApi::class)
6364
override fun init() {
@@ -77,9 +78,16 @@ class ModsOverviewScreen(private val previousScreen: Screen) : Screen(Translatab
7778
sortingButtonWidget = addDrawableChild(
7879
CyclingButtonWidget.builder(Sorting::translations)
7980
.values(Sorting.RELEVANCE, Sorting.DOWNLOADS, Sorting.NEWEST, Sorting.UPDATED)
80-
.build(180, 10, 180, 20, TranslatableText("modmanager.sorting.sort"))
81+
.build(180, 10, 120, 20, TranslatableText("modmanager.sorting.sort"))
8182
{ _: CyclingButtonWidget<Any>, sorting: Sorting -> this.sorting = sorting; updateModList() }
8283
)
84+
updateAll = addDrawableChild(
85+
ButtonWidget(width - 100 - 10, 10, 100, 20, TranslatableText("modmanager.button.updateAll")) {
86+
ModManager.modManager.icons.destroyAll()
87+
client?.setScreen(UpdateAllScreen(this))
88+
}
89+
)
90+
updateAll.visible = false
8391

8492
categoryList = addSelectableChild(
8593
CategoryListWidget(
@@ -150,12 +158,12 @@ class ModsOverviewScreen(private val previousScreen: Screen) : Screen(Translatab
150158
}
151159
if (query.isNotEmpty()) {
152160
showModsBySearch()
161+
modList.scrollAmount = scrollPercentage
153162
return@launch
154163
}
155164
showModsByCategory()
165+
modList.scrollAmount = scrollPercentage
156166
}
157-
modList.init()
158-
categoryList.init()
159167
}
160168

161169
private fun showNextPage() {
@@ -279,6 +287,7 @@ class ModsOverviewScreen(private val previousScreen: Screen) : Screen(Translatab
279287
this.searchField.tick()
280288
this.previousPage.active = page > 0
281289
this.nextPage.active = this.modList.getElementCount() >= limit
290+
this.updateAll.visible = this.selectedCategories.any { it.id == "updatable" }
282291
}
283292

284293
override fun render(matrices: MatrixStack?, mouseX: Int, mouseY: Int, delta: Float) {
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package xyz.deathsgun.modmanager.gui
2+
3+
import kotlinx.coroutines.DelicateCoroutinesApi
4+
import net.minecraft.client.gui.screen.Screen
5+
import net.minecraft.client.gui.screen.ScreenTexts
6+
import net.minecraft.client.gui.widget.ButtonWidget
7+
import net.minecraft.client.util.math.MatrixStack
8+
import net.minecraft.text.TranslatableText
9+
import xyz.deathsgun.modmanager.ModManager
10+
import xyz.deathsgun.modmanager.api.gui.list.IListScreen
11+
import xyz.deathsgun.modmanager.gui.widget.UpdateProgressListWidget
12+
import xyz.deathsgun.modmanager.update.Update
13+
import kotlin.math.min
14+
15+
class UpdateAllScreen(private val parentScreen: Screen) : Screen(TranslatableText("modmanager.title.updating")),
16+
IListScreen {
17+
18+
private lateinit var updateList: UpdateProgressListWidget
19+
private lateinit var doneButton: ButtonWidget
20+
private var updated = ArrayList<String>()
21+
22+
@OptIn(DelicateCoroutinesApi::class)
23+
override fun init() {
24+
updateList = UpdateProgressListWidget(
25+
client!!,
26+
width - 50,
27+
height - 40,
28+
25,
29+
height - 50,
30+
textRenderer.fontHeight + 4,
31+
this
32+
)
33+
updateList.setLeftPos(25)
34+
doneButton = addDrawableChild(ButtonWidget(width / 2 - 100, height - 30, 200, 20, ScreenTexts.DONE) {
35+
onClose()
36+
})
37+
doneButton.active = false
38+
}
39+
40+
override fun render(matrices: MatrixStack, mouseX: Int, mouseY: Int, delta: Float) {
41+
renderBackground(matrices)
42+
updateList.render(matrices, mouseX, mouseY, delta)
43+
textRenderer.draw(matrices, title, (width / 2 - textRenderer.getWidth(title) / 2).toFloat(), 10F, 0xFFFFFF)
44+
super.render(matrices, mouseX, mouseY, delta)
45+
}
46+
47+
override fun mouseScrolled(mouseX: Double, mouseY: Double, amount: Double): Boolean {
48+
return updateList.mouseScrolled(mouseX, mouseY, amount)
49+
}
50+
51+
override fun tick() {
52+
updateList.tick()
53+
val pendingUpdates = getPendingUpdates()
54+
if (pendingUpdates.isEmpty()) {
55+
doneButton.active = true
56+
}
57+
if (pendingUpdates.isEmpty() || !updateList.children().all { it.progress == 1.0 }) {
58+
return
59+
}
60+
for (i in 0..min(1, pendingUpdates.size - 1)) {
61+
val update = pendingUpdates[i]
62+
updated.add(update.mod.id)
63+
updateList.add(update)
64+
updateList.scrollAmount = updateList.maxScroll.toDouble()
65+
}
66+
}
67+
68+
private fun getPendingUpdates(): List<Update> {
69+
return ModManager.modManager.update.getWhitelistedUpdates().filter {
70+
!updated.contains(it.mod.id)
71+
}
72+
}
73+
74+
override fun onClose() {
75+
client?.setScreen(parentScreen)
76+
}
77+
78+
override fun <E> updateSelectedEntry(widget: Any, entry: E?) {
79+
}
80+
81+
override fun <E> updateMultipleEntries(widget: Any, entries: ArrayList<E>) {
82+
}
83+
84+
}

src/main/kotlin/xyz/deathsgun/modmanager/gui/widget/CategoryListWidget.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ class CategoryListWidget(
3131
parent: IListScreen
3232
) : MultiSelectListWidget<CategoryListEntry>(client, width, height, top, bottom, itemHeight, parent) {
3333

34-
override fun init() {
35-
36-
}
37-
3834
fun addCategories(categories: List<Category>) {
3935
categories.forEach {
4036
addEntry(CategoryListEntry(this, it))

0 commit comments

Comments
 (0)