Skip to content
This repository was archived by the owner on Dec 30, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ plugins {
id "fabric-loom" version "0.9-SNAPSHOT"
id "com.modrinth.minotaur" version "1.2.1"
id "org.jetbrains.kotlin.jvm" version "1.5.30"
id 'org.jetbrains.kotlin.plugin.serialization' version '1.5.30'
id "org.jetbrains.kotlin.plugin.serialization" version "1.5.30"
}

sourceCompatibility = JavaVersion.VERSION_16
Expand All @@ -42,10 +42,11 @@ dependencies {
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"

modImplementation "net.fabricmc:fabric-language-kotlin:${project.fabric_kotlin_version}"
modImplementation "com.terraformersmc:modmenu:${project.modmenu_version}"

testImplementation 'org.jetbrains.kotlin:kotlin-test:1.5.21'
testImplementation 'org.jetbrains.kotlin:kotlin-test:1.5.31'
}

processResources {
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/xyz/deathsgun/modmanager/ModManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class ModManager : ClientModInitializer {

@JvmStatic
fun getMinecraftVersion(): String {
return MinecraftClient.getInstance()?.game?.version?.releaseTarget ?: "1.17.1"
return MinecraftClient.getInstance()?.game?.version?.name ?: "1.17.1"
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/kotlin/xyz/deathsgun/modmanager/api/mod/Version.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@

package xyz.deathsgun.modmanager.api.mod

import java.time.LocalDate

data class Version(
val version: String,
val changelog: String,
val releaseDate: LocalDate,
val type: VersionType,
val gameVersions: List<String>,
val assets: List<Asset>
Expand Down
16 changes: 8 additions & 8 deletions src/main/kotlin/xyz/deathsgun/modmanager/config/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,15 @@ data class Config(
fun text(): Text {
return TranslatableText(String.format("modmanager.channel.%s", name.lowercase()))
}
}

fun isReleaseAllowed(type: VersionType): Boolean {
if (updateChannel == UpdateChannel.ALL) {
return true
}
if (updateChannel == UpdateChannel.STABLE && type == VersionType.RELEASE) {
return true
fun isReleaseAllowed(type: VersionType): Boolean {
if (this == ALL) {
return true
}
if (this == STABLE && type == VersionType.RELEASE) {
return true
}
return this == UNSTABLE
}
return updateChannel == UpdateChannel.UNSTABLE
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import java.time.Duration
import java.time.Instant
import java.time.ZoneOffset

@OptIn(ExperimentalSerializationApi::class)
class Modrinth : IModProvider, IModUpdateProvider {
Expand Down Expand Up @@ -211,6 +213,10 @@ class Modrinth : IModProvider, IModUpdateProvider {
Version(
modVersion.version,
modVersion.changelog,
// 2021-09-03T10:56:59.402790Z
Instant.parse(modVersion.releaseDate).atOffset(
ZoneOffset.UTC
).toLocalDate(),
getVersionType(modVersion.type),
modVersion.gameVersions,
assets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ data class ModrinthVersion(
@SerialName("version_number")
val version: String,
val changelog: String,
@SerialName("date_published")
val releaseDate: String,
@SerialName("version_type")
val type: String,
@SerialName("game_versions")
Expand Down
69 changes: 32 additions & 37 deletions src/main/kotlin/xyz/deathsgun/modmanager/update/UpdateManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import net.fabricmc.loader.api.FabricLoader
import net.fabricmc.loader.api.SemanticVersion
import net.fabricmc.loader.api.metadata.ModMetadata
import net.fabricmc.loader.util.version.VersionDeserializer
import net.minecraft.text.TranslatableText
import org.apache.commons.io.FileUtils
import org.apache.logging.log4j.LogManager
Expand Down Expand Up @@ -99,7 +97,12 @@ class UpdateManager {
}
var result = updateProvider.getVersionsForMod(metadata.id)
if (result is VersionResult.Success) {
val version = findLatestCompatible(metadata.version.friendlyString, result.versions)
val version = VersionFinder.findUpdate(
metadata.version.friendlyString,
ModManager.getMinecraftVersion(),
ModManager.modManager.config.updateChannel,
result.versions
)
if (version == null) {
logger.info("No update for {} found!", metadata.id)
ModManager.modManager.setModState(metadata.id, metadata.id, ModState.INSTALLED)
Expand All @@ -117,7 +120,12 @@ class UpdateManager {

val queryResult = provider.search(metadata.name, Sorting.RELEVANCE, 0, 10)
if (queryResult is ModsResult.Error) {
logger.warn("Error while searching for fallback id for mod {}: ", metadata.id, queryResult.cause)
logger.warn(
"Error while searching for fallback id for mod {}: {}",
metadata.id,
queryResult.text.key,
queryResult.cause
)
ModManager.modManager.setModState(metadata.id, metadata.id, ModState.INSTALLED)
return
}
Expand All @@ -136,13 +144,18 @@ class UpdateManager {
result = updateProvider.getVersionsForMod(mod.id)
val versions = when (result) {
is VersionResult.Error -> {
logger.error("Error while getting versions for mod {}", metadata.id)
logger.error("Error while getting versions for mod {}", metadata.id, result.cause)
ModManager.modManager.setModState(metadata.id, mod.id, ModState.INSTALLED)
return
}
is VersionResult.Success -> result.versions
}
val version = findLatestCompatible(metadata.version.friendlyString, versions)
val version = VersionFinder.findUpdate(
metadata.version.friendlyString,
ModManager.getMinecraftVersion(),
ModManager.modManager.config.updateChannel,
versions
)
if (version == null) {
logger.info("No update for {} found!", metadata.id)
ModManager.modManager.setModState(metadata.id, mod.id, ModState.INSTALLED)
Expand Down Expand Up @@ -177,13 +190,18 @@ class UpdateManager {
}
val versions = when (val result = provider.getVersionsForMod(id)) {
is VersionResult.Error -> {
logger.error("Error while getting versions for mod {}", metadata.id)
logger.error("Error while getting versions for mod {}", metadata.id, result.cause)
ModManager.modManager.setModState(metadata.id, id, ModState.INSTALLED)
return
}
is VersionResult.Success -> result.versions
}
val version = findLatestCompatible(metadata.version.friendlyString, versions)
val version = VersionFinder.findUpdate(
metadata.version.friendlyString,
ModManager.getMinecraftVersion(),
ModManager.modManager.config.updateChannel,
versions
)
if (version == null) {
logger.info("No update for {} found!", metadata.id)
ModManager.modManager.setModState(metadata.id, id, ModState.INSTALLED)
Expand Down Expand Up @@ -212,7 +230,12 @@ class UpdateManager {
is VersionResult.Error -> return ModInstallResult.Error(result.text, result.cause)
is VersionResult.Success -> result.versions
}
val version = findLatestCompatible("0.0.0.0", versions)
val version = VersionFinder.findUpdate(
"0.0.0.0",
ModManager.getMinecraftVersion(),
ModManager.modManager.config.updateChannel,
versions
)
?: return ModInstallResult.Error(TranslatableText("modmanager.error.noCompatibleModVersionFound"))

val dir = FabricLoader.getInstance().gameDir.resolve("mods")
Expand Down Expand Up @@ -258,34 +281,6 @@ class UpdateManager {
}
}

private fun findLatestCompatible(installedVersion: String, versions: List<Version>): Version? {
var latest: Version? = null
var latestVersion: SemanticVersion? = null
val installVersion =
VersionDeserializer.deserializeSemantic(installedVersion.split("+")[0]) // Remove additional info from version
for (version in versions) {
if (!version.gameVersions.contains(ModManager.getMinecraftVersion()) ||
!ModManager.modManager.config.isReleaseAllowed(version.type)
) {
continue
}
val ver = try {
VersionDeserializer.deserializeSemantic(version.version.split("+")[0]) // Remove additional info from version
} catch (e: Exception) {
logger.warn("Skipping error producing version {}", version.version)
continue
}
if (latestVersion == null || ver > latestVersion) {
latest = version
latestVersion = ver
}
}
if (latestVersion?.compareTo(installVersion) == 0) {
return null
}
return latest
}

fun updateMod(update: Update): ModUpdateResult {
val oldUpdate = FabricLoader.getInstance().allMods.find { it.metadata.id == update.fabricId }
?: return ModUpdateResult.Error(TranslatableText("modmanager.error.container.notFound"))
Expand Down
86 changes: 86 additions & 0 deletions src/main/kotlin/xyz/deathsgun/modmanager/update/VersionFinder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright 2021 DeathsGun
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package xyz.deathsgun.modmanager.update

import net.fabricmc.loader.api.SemanticVersion
import net.fabricmc.loader.api.VersionParsingException
import net.fabricmc.loader.util.version.VersionDeserializer
import xyz.deathsgun.modmanager.api.mod.Version
import xyz.deathsgun.modmanager.config.Config

object VersionFinder {

fun findUpdateFallback(
installedVersion: String,
mcVersion: String,
updateChannel: Config.UpdateChannel,
modVersions: List<Version>
): Version? {
val versions =
modVersions.filter { updateChannel.isReleaseAllowed(it.type) }
.filter { it.gameVersions.any { it1 -> it1.startsWith(mcVersion) } }
.sortedByDescending { it.releaseDate }

val version = versions.firstOrNull()
if (version?.version == installedVersion) {
return null
}
return version
}

internal fun findUpdateByVersion(
installedVersion: String,
mcVersion: String,
channel: Config.UpdateChannel,
modVersions: List<Version>
): Version? {
val versions = modVersions.filter { channel.isReleaseAllowed(it.type) }
.filter { it.gameVersions.any { it1 -> it1.startsWith(mcVersion) } }
var latestVersion: Version? = null
var latestVer: SemanticVersion? = null
val installedVer = VersionDeserializer.deserializeSemantic(installedVersion)
for (version in versions) {
val parsedVersion = VersionDeserializer.deserializeSemantic(version.version)
if (latestVersion == null) {
latestVersion = version
latestVer = parsedVersion
continue
}
if (latestVer != null && parsedVersion > latestVer) {
latestVersion = version
latestVer = parsedVersion
}
}
if (installedVersion == latestVersion?.version || (latestVer != null && installedVer >= latestVer)) {
return null
}
return latestVersion
}

fun findUpdate(
installedVersion: String,
mcVersion: String,
channel: Config.UpdateChannel,
modVersions: List<Version>
): Version? {
return try {
findUpdateByVersion(installedVersion, mcVersion, channel, modVersions)
} catch (e: VersionParsingException) {
findUpdateFallback(installedVersion, mcVersion, channel, modVersions)
}
}
}
Loading