jakobkmar / pacmc

An easy-to-use package manager (and soon to be launcher) for Minecraft mods.
GNU Affero General Public License v3.0
121 stars 9 forks source link

Curseforge: downloadUrl is null in file response #41

Closed btwonion closed 7 months ago

btwonion commented 2 years ago

When i performed pacmc install entityculling a exception was thrown: kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 406: Expected string literal but 'null' literal was found. Use 'coerceInputValues = true' in 'Json {} builder to coerce nulls to default values. JSON input: .....ownloadCount":0,"downloadUrl":null,"gameVersions":["1.16.3",..... at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:24) at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:32) at kotlinx.serialization.json.internal.AbstractJsonLexer.fail(AbstractJsonLexer.kt:524) at kotlinx.serialization.json.internal.AbstractJsonLexer.unexpectedToken(AbstractJsonLexer.kt:202) at kotlinx.serialization.json.internal.StringJsonLexer.consumeNextToken(StringJsonLexer.kt:74) at kotlinx.serialization.json.internal.StringJsonLexer.consumeKeyString(StringJsonLexer.kt:85) at kotlinx.serialization.json.internal.AbstractJsonLexer.consumeString(AbstractJsonLexer.kt:310) at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeString(StreamingJsonDecoder.kt:256) at kotlinx.serialization.encoding.AbstractDecoder.decodeStringElement(AbstractDecoder.kt:58) at net.axay.pacmc.repoapi.curseforge.model.File$$serializer.deserialize(File.kt:6) at net.axay.pacmc.repoapi.curseforge.model.File$$serializer.deserialize(File.kt:6) at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:59) at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:36) at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43) at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70) at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:535) at kotlinx.serialization.internal.ListLikeSerializer.readElement(CollectionSerializers.kt:80) at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51) at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36) at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43) at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:59) at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:36) at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43) at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70) at net.axay.pacmc.repoapi.curseforge.model.CurseforgeDataWrapper$$serializer.deserialize(CurseforgeDataWrapper.kt:5) at net.axay.pacmc.repoapi.curseforge.model.CurseforgeDataWrapper$$serializer.deserialize(CurseforgeDataWrapper.kt:5) at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:59) at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:36) at kotlinx.serialization.internal.NullableSerializer.deserialize(NullableSerializer.kt:30) at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:59) at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:36) at kotlinx.serialization.json.Json.decodeFromString(Json.kt:100) at net.axay.pacmc.repoapi.curseforge.CurseforgeApi$getProjectVersions$2$1$1.invokeSuspend(CurseforgeApi.kt:116) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:749) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)

endrjux commented 2 years ago

@jakobkmar mentioned in #43 that this is not a pacmc bug. Some mods can't be downloaded by 3rd party app and mod author needs to change that in project settings on Curseforge.

Since pacmc can find such mod and is able to resolve its info (version etc), would it be possible to implement a feature where pacmc still manages the mod but user needs to download it manually? (So that pacmc can notify user when update is needed etc). The simplest way I can think of is just adding --source-file argument to install command to tell pacmc where the downloaded mod file is.

jakobkmar commented 2 years ago

@endrjux the idea that pacmc should still manage the mod and just not download it is actually good - I'll consider it if there are a lot of mods which don't enable redistribution and are not available on Modrinth.

endrjux commented 2 years ago

Out of 49 mods I use, 7 have this problem and none of them are on Modrinth unfortunately. Three of them have more than 1M downloads so I guess that counts as somewhat popular (entityculling almost 6M, client-tweaks-fabric almost 1.5M, item-highlighter-fabric over 1M), other are significantly less popular.

I think people complain about similar issue on cf: https://www.curseforge.com/minecraft/mc-mods/entityculling#c293 I'm not entirely sure I understand it correctly but it looks like mod author doesn't want to enable that feature on cf and doesn't really want to use Modrinth as well. That's of course just one mod, but my point is contacting author or using Modrinth may not be a guaranteed way to solve this issue... (entityculling author says it's a license issue, this might also be true for other mods)

Later: another example is cloth-config. Author explicitly stated they don't want to use Modrinth (https://github.com/shedaniel/cloth-config/issues/150 eventually leads to https://github.com/shedaniel/cloth-api/issues/38). This mod is a dependency of other mods and it too can't be installed using pacmc.

endrjux commented 2 years ago

@btwonion FYI: entityculling is now available on Modrinth so you can install it using pacmc install modrinth/entityculling.

WordlessEcho commented 2 years ago

I have to say that you should not trust any data from outside the program. It should be replaced by user-friendly prompts.