diff --git a/src/main/scala/sc4pac/ChannelUtil.scala b/src/main/scala/sc4pac/ChannelUtil.scala index 5c3b823..14de1e6 100644 --- a/src/main/scala/sc4pac/ChannelUtil.scala +++ b/src/main/scala/sc4pac/ChannelUtil.scala @@ -138,7 +138,7 @@ object ChannelUtil { // write channel contents val channel = { - val c = JD.Channel.create(scheme = Constants.currentChannelScheme, packagesMap) + val c = JD.Channel.create(scheme = Constants.channelSchemeVersions.max, packagesMap) c.copy(contents = c.contents.sortBy(item => (item.group, item.name))) } scala.util.Using.resource(java.nio.file.Files.newBufferedWriter((tempJsonDir / JsonRepoUtil.channelContentsFilename).toNIO)) { out => diff --git a/src/main/scala/sc4pac/Constants.scala b/src/main/scala/sc4pac/Constants.scala index dcdd7c5..750e1e7 100644 --- a/src/main/scala/sc4pac/Constants.scala +++ b/src/main/scala/sc4pac/Constants.scala @@ -15,11 +15,21 @@ object Constants { val sc4fileTypePattern = Pattern.compile("""\.dat|\.sc4model|\.sc4lot|\.sc4desc|\.sc4|\.dll$""", Pattern.CASE_INSENSITIVE) val versionLatestRelease = "latest.release" val defaultChannelUrls = Seq(MetadataRepository.parseChannelUrl("https://memo33.github.io/sc4pac/channel/").toOption.get) - // scheme version history: + + // Channels are built with the maximum version. + // When incrementing the maximum, older sc4pac clients become incompatible + // with newer channels, forcing users to upgrade their clients. + // + // When incrementing the minimum, older channels become incompatible with + // newer sc4pac clients, forcing channel maintainers to rebuild the channels. + // The minimum must be incremented when introducing backward-incompatible changes. + // + // Scheme version history: // 1: initial version // 2: DLL support and single-file assets // 3: rar support - val currentChannelScheme = 3 // version number (incrementing this forces everyone accessing the channel to install a newer sc4pac version) + val channelSchemeVersions: Range = 1 to 3 // supported versions + val bufferSizeExtract = 64 * 1024 // 64 kiB, bounded by disk speed val bufferSizeDownload = 1024 * 1024 // 1 MiB, bounded by download speed val bufferSizeDownloadOverlap = 4 * 1024 // for file validity check when resuming partial download diff --git a/src/main/scala/sc4pac/MetadataRepository.scala b/src/main/scala/sc4pac/MetadataRepository.scala index dfbbb19..41e1ce7 100644 --- a/src/main/scala/sc4pac/MetadataRepository.scala +++ b/src/main/scala/sc4pac/MetadataRepository.scala @@ -140,12 +140,13 @@ object MetadataRepository { jsonVal <- ZIO.attemptBlockingIO(ujson.read(channelContentsFile.toNIO)) .mapError(e => s"Failed to read channel contents: $e") scheme = jsonVal.objOpt.flatMap(_.get("scheme")).map(_.num.toInt).getOrElse(0) - _ <- ZIO.when(scheme <= 0)(ZIO.fail( - s"The channel $contentsUrl uses an old scheme ($scheme) that is not supported anymore." + _ <- ZIO.when(scheme < Constants.channelSchemeVersions.min)(ZIO.fail( + s"The channel $contentsUrl uses an old scheme ($scheme) that is not supported anymore by your version of sc4pac." + + " Contact the maintainer of the channel." )) - _ <- ZIO.when(scheme > Constants.currentChannelScheme)(ZIO.fail( + _ <- ZIO.when(scheme > Constants.channelSchemeVersions.max)(ZIO.fail( s"The channel $contentsUrl has a newer scheme ($scheme) than supported " + - s"by your installation (${Constants.currentChannelScheme}). Please update to the latest version of sc4pac." + s"by your installation (${Constants.channelSchemeVersions}). Please update to the latest version of sc4pac." )) channel <- ZIO.attemptBlockingIO(JsonIo.readBlocking[JD.Channel](jsonVal, errMsg = contentsUrl)) .mapError(e => s"Failed to read channel contents: $e") @@ -242,7 +243,7 @@ private class YamlRepository( // We pick the latest scheme version as we do not have any other input to work with. // If the scheme has been updated, then the yaml files have probably already failed to parse. - lazy private val channel = JD.Channel.create(scheme = Constants.currentChannelScheme, channelData) + lazy private val channel = JD.Channel.create(scheme = Constants.channelSchemeVersions.max, channelData) def iterateChannelContents: Iterator[JD.ChannelItem] = channel.contents.iterator }