Skip to content

Commit

Permalink
add curseforge support to updates
Browse files Browse the repository at this point in the history
  • Loading branch information
DeDiamondPro committed Dec 10, 2024
1 parent fb2b7b2 commit b7025e9
Show file tree
Hide file tree
Showing 15 changed files with 475 additions and 153 deletions.
8 changes: 4 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ tasks {

if (platform.isForge && platform.mcVersion >= 12100) {
exclude("forge.mixins.resourcify.refmap.json")
archiveFileName.set("$mod_name (${getPrettyVersionRange()}-${platform.loaderStr})-${mod_version}.jar")
archiveFileName.set("$mod_name (${getPrettyVersionRange(true)}-${platform.loaderStr})-${mod_version}.jar")
}
}
remapJar {
Expand All @@ -247,7 +247,7 @@ tasks {
input.set(shadowJar.get().archiveFile)
archiveClassifier.set("")
finalizedBy("copyJar")
archiveFileName.set("$mod_name (${getPrettyVersionRange()}-${platform.loaderStr})-${mod_version}.jar")
archiveFileName.set("$mod_name (${getPrettyVersionRange(true)}-${platform.loaderStr})-${mod_version}.jar")
if (platform.isForgeLike && platform.mcVersion >= 12004) {
atAccessWideners.add("resourcify.accesswidener")
}
Expand Down Expand Up @@ -374,10 +374,10 @@ fun getSupportedVersionRange(): Pair<String, String?> = when (platform.mcVersion
else -> error("Undefined version range for ${platform.mcVersion}")
}

fun getPrettyVersionRange(): String {
fun getPrettyVersionRange(forFile: Boolean = false): String {
val supportedVersionRange = getSupportedVersionRange()
return when {
supportedVersionRange.first == "1.21.2" -> "1.21.3-4"
supportedVersionRange.first == "1.21.2" -> if (forFile) "1.21.3-4" else "1.21.3/4"
supportedVersionRange.first == "1.21.1" -> "1.21.1"
supportedVersionRange.first == supportedVersionRange.second -> supportedVersionRange.first
listOf("1.16", "1.18").contains(supportedVersionRange.first) -> "${supportedVersionRange.first}.x"
Expand Down
12 changes: 10 additions & 2 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
## Resourcify 1.5.2
## Resourcify 1.6.0

- When possible, links to modrinth in a project description will now be opened in Resourcify.
### New features

- Add **CurseForge support for updating**! Resourcify will now check both Modrinth and Curseforge for updates, and you
can choose which source to use per project.
- When possible, links to modrinth in a project description will now be opened in Resourcify (this is configurable in
the config).
- Add support for side mouse buttons to go back and forward between pages.

### Fixes

- Fix CurseForge version filter using major version instead of exact version.
- You can now select multiple Minecraft versions when using the CurseForge source.

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
mod_name = Resourcify
mod_id = resourcify
mod_version = 1.5.2
mod_version = 1.6.0

org.gradle.daemon=true
org.gradle.parallel=true
Expand Down
87 changes: 87 additions & 0 deletions src/main/java/dev/dediamondpro/resourcify/util/MurmurHash2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* This file is part of Resourcify
* Copyright (C) 2024 DeDiamondPro
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License Version 3 as published by the Free Software Foundation.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package dev.dediamondpro.resourcify.util;

// Written in java because I don't like kotlin's bit operators
public class MurmurHash2 {
private static boolean isWhiteSpaceCharacter(byte b) {
return b == 9 || b == 10 || b == 13 || b == 32;
}

public static long cfHash(byte[] data, int length) {
// "Normalize" the byte array
// Adapted from https://github.com/CurseForgeCommunity/.NET-APIClient/blob/2c4f5f613d20025f9286fdd53592f8519022918f/Murmur2.cs
// To avoid creating a copy in memory we will shift the existing data in the array
int shiftCount = 0;
for (int i = 0; i < length; i++) {
if (isWhiteSpaceCharacter(data[i])) {
shiftCount++;
} else {
data[i - shiftCount] = data[i];
}
}
int hash = hash32(data, length - shiftCount, 1);
// Extend to long without extending the sign, avoid getting negative numbers
return hash & 0xFFFFFFFFL;
}

/**
* Taken from https://github.com/tnm/murmurhash-java/blob/1cef5b1bdb1856d1d4d48b5572f35baacb57d0f5/src/main/java/ie/ucd/murmur/MurmurHash.java#L33-L67
* Under the public domain
*/
public static int hash32(final byte[] data, int length, int seed) {
// 'm' and 'r' are mixing constants generated offline.
// They're not really 'magic', they just happen to work well.
final int m = 0x5bd1e995;
final int r = 24;

// Initialize the hash to a random value
int h = seed ^ length;
int length4 = length / 4;

for (int i = 0; i < length4; i++) {
final int i4 = i * 4;
int k = (data[i4] & 0xff)
+ ((data[i4 + 1] & 0xff) << 8)
+ ((data[i4 + 2] & 0xff) << 16)
+ ((data[i4 + 3] & 0xff) << 24);
k *= m;
k ^= k >>> r;
k *= m;
h *= m;
h ^= k;
}

// Handle the last few bytes of the input array
switch (length % 4) {
case 3:
h ^= (data[(length & ~3) + 2] & 0xff) << 16;
case 2:
h ^= (data[(length & ~3) + 1] & 0xff) << 8;
case 1:
h ^= (data[length & ~3] & 0xff);
h *= m;
}

h ^= h >>> 13;
h *= m;
h ^= h >>> 15;

return h;
}
}
75 changes: 44 additions & 31 deletions src/main/kotlin/dev/dediamondpro/resourcify/config/SettingsPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,37 +55,10 @@ class SettingsPage() : PaginatedScreen(adaptScale = false) {
} childOf mainBox

// Source
val sourceBox = UIBlock(Color(0, 0, 0, 100)).constrain {
x = 0.pixels()
y = SiblingConstraint(padding = 4f)
width = 100.percent()
height = ChildBasedMaxSizeConstraint() + 4.pixels()
} childOf mainBox
val sourceDescriptionBox = UIContainer().constrain {
x = 4.pixels()
y = 4.pixels()
width = 100.percent() - 168.pixels()
height = ChildLocationSizeConstraint()
} childOf sourceBox
UIWrappedText("resourcify.config.source.title".localize()).constrain {
width = 100.percent()
} childOf sourceDescriptionBox
UIWrappedText("resourcify.config.source.description".localize()).constrain {
y = SiblingConstraint(padding = 4f)
width = 100.percent()
color = Color.LIGHT_GRAY.toConstraint()
} childOf sourceDescriptionBox
DropDown(
ServiceRegistry.getAllServices().map { it.getName() },
true, mutableListOf(Config.instance.defaultService)
).constrain {
x = 4.pixels(true)
y = CenterConstraint()
width = 160.pixels()
}.onSelectionUpdate {
Config.instance.defaultService = it.first()
Config.save()
} childOf sourceBox
val allServices = ServiceRegistry.getAllServices().map { it.getName() }
addDropdownOption("resourcify.config.source", allServices, Config.instance.defaultService) {
Config.instance.defaultService = it
}

// Thumbnail quality
addCheckBoxOption("resourcify.config.thumbnail", Config.instance.fullResThumbnail) {
Expand Down Expand Up @@ -146,4 +119,44 @@ class SettingsPage() : PaginatedScreen(adaptScale = false) {
Config.save()
} childOf box
}

private fun addDropdownOption(
localizationString: String,
options: List<String>,
selectedOption: String,
onUpdate: (String) -> Unit
) {
val box = UIBlock(Color(0, 0, 0, 100)).constrain {
x = 0.pixels()
y = SiblingConstraint(padding = 4f)
width = 100.percent()
height = ChildBasedMaxSizeConstraint() + 4.pixels()
} childOf mainBox
val sourceDescriptionBox = UIContainer().constrain {
x = 4.pixels()
y = 4.pixels()
width = 100.percent() - 168.pixels()
height = ChildLocationSizeConstraint()
} childOf box
UIWrappedText("$localizationString.title".localize()).constrain {
width = 100.percent()
} childOf sourceDescriptionBox
UIWrappedText("$localizationString.description".localize()).constrain {
y = SiblingConstraint(padding = 4f)
width = 100.percent()
color = Color.LIGHT_GRAY.toConstraint()
} childOf sourceDescriptionBox
DropDown(
options, true, mutableListOf(
if (options.contains(selectedOption)) selectedOption else options.first()
)
).constrain {
x = 4.pixels(true)
y = CenterConstraint()
width = 160.pixels()
}.onSelectionUpdate {
onUpdate(it.first())
Config.save()
} childOf box
}
}
Loading

0 comments on commit b7025e9

Please sign in to comment.