From 6a20037ed3d626e9b06b2249f6d69ff86fffb7a2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20Kleinekath=C3=B6fer?= <git@felixoi.com>
Date: Mon, 6 Sep 2021 22:04:31 +0200
Subject: [PATCH] 2.0.0-M2.5 (#1049)

* Update for plugin-meta 0.8.0 for API 8 meta changes (#1043)

* Update for plugin-meta 0.8.0 for API 8 meta changes

* Fix for scalafmt

* Once more, with feeling...

* Don't return a partially created data value seq if an error was thrown

* Move to the 0.8.0 release

* Update for comments

Co-authored-by: Chris Sanders <zidane@spongepowered.org>

* plugins.json -> sponge_plugins.json

Forgot to update this...

* Ensure input streams are not closed when finding meta files (#1045)

* Ensure input streams are not closed when finding meta files

plugin-meta 0.8 closes streams when it's read the metadata. We override the close() method to prevent that from happening.

* Formatting

* I'll get this right

* Work around recommended version not being a restriction for deps (#1046)

* Removed triplequote (#1047)

* Removed triplequote

* Delete triplequote_black.svg

* Delete triplequote_white.svg

* Update README.md

* Update Settings.scala (#1048)

Co-authored-by: Daniel Naylor <1904167+dualspiral@users.noreply.github.com>
Co-authored-by: Chris Sanders <zidane@spongepowered.org>
---
 README.md                                     |  31 ----
 .../models/querymodels/apiV2QueryModels.scala |   2 +-
 build.sbt                                     |   1 +
 ore/conf/ore-default-settings.conf            |   5 -
 .../images/sponsors/triplequote_black.svg     |   1 -
 .../images/sponsors/triplequote_white.svg     |   1 -
 .../ore/models/project/io/PluginFile.scala    |   6 +-
 .../models/project/io/PluginFileData.scala    | 144 +++++-------------
 project/Settings.scala                        |   2 +-
 project/dependencies.scala                    |   6 +-
 10 files changed, 53 insertions(+), 146 deletions(-)
 delete mode 100644 ore/public/images/sponsors/triplequote_black.svg
 delete mode 100644 ore/public/images/sponsors/triplequote_white.svg

diff --git a/README.md b/README.md
index af9bcbe71..74a286c87 100644
--- a/README.md
+++ b/README.md
@@ -62,34 +62,3 @@ For `jobs`:
 more stack size to sbt in the way you're starting sbt. `-Xss4m` should be enough. If you're using IntelliJ, you can set 
 this in the VM arguments field. If you're invoking sbt directly, the most common ways to set this is either through 
 the `SBT_OPTS` environment variable, or with a file named `.jvmopts` with each flag on a new line.
-
-### Using Hydra
-
-Hydra is the world’s only parallel compiler for the Scala language.
-Its design goal is to take advantage of the many cores available in modern hardware to parallelize compilation of Scala sources.
-This gives us the possibility to achieve a much faster compile time.
-[Triplequote](https://triplequote.com/) has kindly provided us with some licenses.
-If you have a license and want to use Hydra, follow these steps:
-
-1. Create the file `project/hydra.sbt`
-2. Put in this content into the newly created file:
-   ```
-   credentials += Credentials("Artifactory Realm",
-       "repo.triplequote.com",
-       "<username>",
-       "<password>")
-   resolvers += Resolver.url("Triplequote Plugins Releases", url("https://repo.triplequote.com/artifactory/sbt-plugins-release/"))(Resolver.ivyStylePatterns)
-   addSbtPlugin("com.triplequote" % "sbt-hydra" % "<version>")
-   ```
-   - The `<username>` and `<password>` placeholders have to be replaced with your credentials.
-   - The `<version>` placeholder has to be replaced with the lastest version of `sbt-hydra` which can be obtained from the [offical changelog](https://docs.triplequote.com/changelog/).
-
-3. Open the sbt console and make use of the following command where `<license key>` is your personal hydra license key:
-
-   ```
-   hydraActivateLicense <license key>
-   ```
-
-4. Go and start compiling!
-
-Further instructions can be found at the [official Hydra documentation](https://docs.triplequote.com/).
diff --git a/apiV2/app/models/querymodels/apiV2QueryModels.scala b/apiV2/app/models/querymodels/apiV2QueryModels.scala
index 9505de1eb..e0be57e02 100644
--- a/apiV2/app/models/querymodels/apiV2QueryModels.scala
+++ b/apiV2/app/models/querymodels/apiV2QueryModels.scala
@@ -167,7 +167,7 @@ object APIV2QueryProject {
                   //This will crash and burn if the implementation becomes
                   //something else, but better that, than failing silently
                   case version: DefaultArtifactVersion =>
-                    if (BigInt(version.getVersion.getFirstInteger) >= 28) {
+                    if (BigInt(version.version.getFirstInteger) >= 28) {
                       Some(version.toString) //Not sure what we really want to do here
                     } else {
                       version.toString match {
diff --git a/build.sbt b/build.sbt
index ecc4496f0..c2b170a82 100755
--- a/build.sbt
+++ b/build.sbt
@@ -97,6 +97,7 @@ lazy val orePlayCommon: Project = project
     libraryDependencies ++= Seq(caffeine, ws),
     libraryDependencies ++= Seq(
       Deps.pluginMeta,
+      Deps.pluginMetaMcMod,
       Deps.slickPlay,
       Deps.zio,
       Deps.zioCats,
diff --git a/ore/conf/ore-default-settings.conf b/ore/conf/ore-default-settings.conf
index a1f8a15c7..f4b6450a9 100644
--- a/ore/conf/ore-default-settings.conf
+++ b/ore/conf/ore-default-settings.conf
@@ -243,11 +243,6 @@ sponge {
           "image": "images/sponsors/creeperhost.svg",
           "link": "https://billing.creeperhost.net/link.php?id=8"
         },
-        {
-          "name": "Triplequote",
-          "image": "images/sponsors/triplequote_black.svg",
-          "link": "https://triplequote.com/hydra"
-        },
         {
           "name": "JetBrains",
           "image": "images/sponsors/jetbrains.svg",
diff --git a/ore/public/images/sponsors/triplequote_black.svg b/ore/public/images/sponsors/triplequote_black.svg
deleted file mode 100644
index 7b940fcf1..000000000
--- a/ore/public/images/sponsors/triplequote_black.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 936.7 176.8"><defs><style>.cls-3{fill:#000}</style><clipPath id="clip-path"><path fill="none" d="M0 0h936.7v176.8H0z"/></clipPath></defs><g clip-path="url(#clip-path)"><path class="cls-3" d="M176.6 48.2h-11.8v-6.8h11.8V16.1h7.5v25.3h23.4v6.8h-23.4v49c0 23.5 14.1 26.6 21.2 26.6a18.54 18.54 0 0 0 4.1-.4v7a22.8 22.8 0 0 1-4.5.4c-9.3 0-28.4-3.4-28.4-33V48.2zM220.8 40.9h7.5v16.9a37.93 37.93 0 0 1-.7 7.3h.4c4.5-13.7 14.4-25 28.5-25a30 30 0 0 1 5.2.5v7.5a25.35 25.35 0 0 0-4.1-.4c-13.9 0-22.6 11.8-26.6 25a61.77 61.77 0 0 0-2.7 18.7v38.5h-7.5zM271.4 5.3h8.9v13h-8.9zm.7 35.6h7.5v89.2h-7.5zM302.1 40.9h7.5v10.7a47.82 47.82 0 0 1-.5 7.1h.4s7.3-20 32.1-20c23.9 0 38.5 19.1 38.5 46.7 0 28.4-16.6 46.7-39.6 46.7-23.2 0-31.2-20.2-31.2-20.2h-.4a40.26 40.26 0 0 1 .7 7.8v45.8h-7.5zm38.3 84c17.5 0 31.7-14.4 31.7-39.4 0-24.1-12.8-39.4-31-39.4-16.4 0-31.7 11.6-31.7 39.6 0 19.8 11.1 39.2 31 39.2M395.5 5.3h7.5v104.5c0 12.5 6.4 13.9 10.5 13.9a20.12 20.12 0 0 0 2.7-.2v7a15.14 15.14 0 0 1-3.2.4c-5.2 0-17.5-2-17.5-18.7zM465.6 38.8c24.3 0 36.4 19.1 36.4 40.7a42.11 42.11 0 0 1-.4 4.8h-71.5c0 25.9 17.5 40.7 38.2 40.7a40.32 40.32 0 0 0 27.6-11.2l4.1 6.2a48.61 48.61 0 0 1-31.7 12.3c-25.1 0-46-18.2-46-46.5 0-30.2 20.5-47 43.3-47m28.5 38.5c-.9-21.8-13.9-31.6-28.7-31.6-16.4 0-31.6 10.7-34.8 31.6zM557.8 38.8A45.84 45.84 0 0 1 604 85c0 26.6-20.7 47.3-46.2 47.3s-46.2-20.7-46.2-47.3a45.84 45.84 0 0 1 46.2-46.2m0 86.1c21.2 0 38.3-17.3 38.3-39.9 0-22.1-17.1-38.9-38.3-38.9S519.5 62.9 519.5 85c-.1 22.6 17.1 39.9 38.3 39.9M618.6 40.9h7.5v53.9c0 15.5 2 30.1 21.9 30.1 22.3 0 36.6-19.6 36.6-40.5V40.9h7.5v89.2h-7.5v-15.7a37.93 37.93 0 0 1 .7-7.3h-.4c-3 8.4-15.3 25.1-36.9 25.1-21.9 0-29.4-12.1-29.4-34.8zM754.1 38.8A45.84 45.84 0 0 1 800.3 85c0 26.6-20.7 47.3-46.2 47.3s-46.2-20.7-46.2-47.3a45.84 45.84 0 0 1 46.2-46.2m0 86.1c21.2 0 38.3-17.3 38.3-39.9 0-22.1-17.1-38.9-38.3-38.9S715.8 62.9 715.8 85c0 22.6 17.1 39.9 38.3 39.9M819 48.2h-11.8v-6.8H819V16.1h7.5v25.3h23.4v6.8h-23.4v49c0 23.5 14.1 26.6 21.2 26.6a18.55 18.55 0 0 0 4.1-.4v7a22.8 22.8 0 0 1-4.5.4c-9.3 0-28.4-3.4-28.4-33V48.2zM900.3 38.8c24.3 0 36.4 19.1 36.4 40.7a42.12 42.12 0 0 1-.4 4.8h-71.5c0 25.9 17.5 40.7 38.2 40.7a40.32 40.32 0 0 0 27.6-11.2l4.1 6.2a48.61 48.61 0 0 1-31.7 12.3c-25.1 0-46-18.2-46-46.5 0-30.2 20.5-47 43.3-47m28.5 38.5c-.9-21.8-13.9-31.6-28.7-31.6-16.4 0-31.6 10.7-34.8 31.6z"/><path class="cls-3" d="M556.2 124.9h49.2v7.3h-49.2zM122.4 0h2.1v176.8h-2.1zM0 15.8h8.8v29.6H0zM14.5 15.8h8.8v29.6h-8.8zM42.9 15.8h8.8v29.6h-8.8zM57.3 15.8h8.8v29.6h-8.8zM85.8 15.8h8.8v29.6h-8.8zM100.2 15.8h8.8v29.6h-8.8z"/></g></svg>
\ No newline at end of file
diff --git a/ore/public/images/sponsors/triplequote_white.svg b/ore/public/images/sponsors/triplequote_white.svg
deleted file mode 100644
index 21e26386a..000000000
--- a/ore/public/images/sponsors/triplequote_white.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 936.7 176.8"><defs><style>.cls-3{fill:#fff}</style><clipPath id="clip-path"><path fill="none" d="M0 0h936.7v176.8H0z"/></clipPath></defs><g clip-path="url(#clip-path)"><path class="cls-3" d="M176.6 48.2h-11.8v-6.8h11.8V16.1h7.5v25.3h23.4v6.8h-23.4v49c0 23.5 14.1 26.6 21.2 26.6a18.54 18.54 0 0 0 4.1-.4v7a22.8 22.8 0 0 1-4.5.4c-9.3 0-28.4-3.4-28.4-33V48.2zM220.8 40.9h7.5v16.9a37.93 37.93 0 0 1-.7 7.3h.4c4.5-13.7 14.4-25 28.5-25a30 30 0 0 1 5.2.5v7.5a25.35 25.35 0 0 0-4.1-.4c-13.9 0-22.6 11.8-26.6 25a61.77 61.77 0 0 0-2.7 18.7v38.5h-7.5zM271.4 5.3h8.9v13h-8.9zm.7 35.6h7.5v89.2h-7.5zM302.1 40.9h7.5v10.7a47.82 47.82 0 0 1-.5 7.1h.4s7.3-20 32.1-20c23.9 0 38.5 19.1 38.5 46.7 0 28.4-16.6 46.7-39.6 46.7-23.2 0-31.2-20.2-31.2-20.2h-.4a40.26 40.26 0 0 1 .7 7.8v45.8h-7.5zm38.3 84c17.5 0 31.7-14.4 31.7-39.4 0-24.1-12.8-39.4-31-39.4-16.4 0-31.7 11.6-31.7 39.6 0 19.8 11.1 39.2 31 39.2M395.5 5.3h7.5v104.5c0 12.5 6.4 13.9 10.5 13.9a20.12 20.12 0 0 0 2.7-.2v7a15.14 15.14 0 0 1-3.2.4c-5.2 0-17.5-2-17.5-18.7zM465.6 38.8c24.3 0 36.4 19.1 36.4 40.7a42.11 42.11 0 0 1-.4 4.8h-71.5c0 25.9 17.5 40.7 38.2 40.7a40.32 40.32 0 0 0 27.6-11.2l4.1 6.2a48.61 48.61 0 0 1-31.7 12.3c-25.1 0-46-18.2-46-46.5 0-30.2 20.5-47 43.3-47m28.5 38.5c-.9-21.8-13.9-31.6-28.7-31.6-16.4 0-31.6 10.7-34.8 31.6zM557.8 38.8A45.84 45.84 0 0 1 604 85c0 26.6-20.7 47.3-46.2 47.3s-46.2-20.7-46.2-47.3a45.84 45.84 0 0 1 46.2-46.2m0 86.1c21.2 0 38.3-17.3 38.3-39.9 0-22.1-17.1-38.9-38.3-38.9S519.5 62.9 519.5 85c-.1 22.6 17.1 39.9 38.3 39.9M618.6 40.9h7.5v53.9c0 15.5 2 30.1 21.9 30.1 22.3 0 36.6-19.6 36.6-40.5V40.9h7.5v89.2h-7.5v-15.7a37.93 37.93 0 0 1 .7-7.3h-.4c-3 8.4-15.3 25.1-36.9 25.1-21.9 0-29.4-12.1-29.4-34.8zM754.1 38.8A45.84 45.84 0 0 1 800.3 85c0 26.6-20.7 47.3-46.2 47.3s-46.2-20.7-46.2-47.3a45.84 45.84 0 0 1 46.2-46.2m0 86.1c21.2 0 38.3-17.3 38.3-39.9 0-22.1-17.1-38.9-38.3-38.9S715.8 62.9 715.8 85c0 22.6 17.1 39.9 38.3 39.9M819 48.2h-11.8v-6.8H819V16.1h7.5v25.3h23.4v6.8h-23.4v49c0 23.5 14.1 26.6 21.2 26.6a18.55 18.55 0 0 0 4.1-.4v7a22.8 22.8 0 0 1-4.5.4c-9.3 0-28.4-3.4-28.4-33V48.2zM900.3 38.8c24.3 0 36.4 19.1 36.4 40.7a42.12 42.12 0 0 1-.4 4.8h-71.5c0 25.9 17.5 40.7 38.2 40.7a40.32 40.32 0 0 0 27.6-11.2l4.1 6.2a48.61 48.61 0 0 1-31.7 12.3c-25.1 0-46-18.2-46-46.5 0-30.2 20.5-47 43.3-47m28.5 38.5c-.9-21.8-13.9-31.6-28.7-31.6-16.4 0-31.6 10.7-34.8 31.6z"/><path class="cls-3" d="M556.2 124.9h49.2v7.3h-49.2zM122.4 0h2.1v176.8h-2.1zM0 15.8h8.8v29.6H0zM14.5 15.8h8.8v29.6h-8.8zM42.9 15.8h8.8v29.6h-8.8zM57.3 15.8h8.8v29.6h-8.8zM85.8 15.8h8.8v29.6h-8.8zM100.2 15.8h8.8v29.6h-8.8z"/></g></svg>
\ No newline at end of file
diff --git a/orePlayCommon/app/ore/models/project/io/PluginFile.scala b/orePlayCommon/app/ore/models/project/io/PluginFile.scala
index fc458abc3..0401fa2bc 100644
--- a/orePlayCommon/app/ore/models/project/io/PluginFile.scala
+++ b/orePlayCommon/app/ore/models/project/io/PluginFile.scala
@@ -49,7 +49,11 @@ class PluginFile(val path: Path, val user: Model[User]) {
               .continually(jarIn.getNextJarEntry)
               .takeWhile(_ != null) // scalafix:ok
               .filter(entry => fileNames.contains(entry.getName))
-              .flatMap(entry => PluginFileData.getData(entry.getName, new BufferedReader(new InputStreamReader(jarIn))))
+              .flatMap { entry =>
+                PluginFileData.getData(entry.getName, new BufferedReader(new InputStreamReader(jarIn)) {
+                  override def close(): Unit = {}
+                })
+              }
               .toVector
 
             // Mainfest file isn't read in the jar stream for whatever reason
diff --git a/orePlayCommon/app/ore/models/project/io/PluginFileData.scala b/orePlayCommon/app/ore/models/project/io/PluginFileData.scala
index b4bdb7324..0f90eb737 100644
--- a/orePlayCommon/app/ore/models/project/io/PluginFileData.scala
+++ b/orePlayCommon/app/ore/models/project/io/PluginFileData.scala
@@ -1,19 +1,18 @@
 package ore.models.project.io
 
 import scala.language.higherKinds
-
 import java.io.BufferedReader
-import com.google.gson.stream.JsonReader
 
 import scala.collection.mutable.ArrayBuffer
 import scala.jdk.CollectionConverters._
+import scala.jdk.OptionConverters._
 import scala.util.control.NonFatal
-
 import ore.data.project.Dependency
 import ore.db.{DbRef, Model, ModelService}
 import ore.models.project.{TagColor, Version, VersionTag}
-
 import org.spongepowered.plugin.meta.McModInfo
+import org.spongepowered.plugin.metadata.builtin.MetadataParser
+import org.spongepowered.plugin.metadata.model.PluginDependency
 
 /**
   * The metadata within a [[PluginFile]]
@@ -155,26 +154,26 @@ object McModInfoHandler extends FileTypeHandler("mcmod.info") {
       else {
         val metadata = info.head
 
-        if (metadata.getId != null)
-          dataValues += StringDataValue("id", metadata.getId)
+        if (metadata.id != null)
+          dataValues += StringDataValue("id", metadata.id)
 
-        if (metadata.getVersion != null)
-          dataValues += StringDataValue("version", metadata.getVersion)
+        if (metadata.version != null)
+          dataValues += StringDataValue("version", metadata.version)
 
-        if (metadata.getName != null)
-          dataValues += StringDataValue("name", metadata.getName)
+        if (metadata.name != null)
+          dataValues += StringDataValue("name", metadata.name)
 
-        if (metadata.getDescription != null)
-          dataValues += StringDataValue("description", metadata.getDescription)
+        if (metadata.description != null)
+          dataValues += StringDataValue("description", metadata.description)
 
-        if (metadata.getUrl != null)
-          dataValues += StringDataValue("url", metadata.getUrl)
+        if (metadata.url != null)
+          dataValues += StringDataValue("url", metadata.url)
 
-        if (metadata.getAuthors != null)
-          dataValues += StringListValue("authors", metadata.getAuthors.asScala.toSeq)
+        if (metadata.authors != null)
+          dataValues += StringListValue("authors", metadata.authors.asScala.toSeq)
 
-        if (metadata.getDependencies != null) {
-          val dependencies = metadata.getDependencies.asScala.map(p => Dependency(p.getId, Option(p.getVersion))).toSeq
+        if (metadata.dependencies != null) {
+          val dependencies = metadata.dependencies.asScala.map(p => Dependency(p.id, Option(p.version()))).toSeq
           dataValues += DependencyDataValue("dependencies", dependencies)
         }
 
@@ -209,98 +208,35 @@ object ModTomlHandler extends FileTypeHandler("mod.toml") {
     Nil
 }
 
-object SpongeJsonHandler extends FileTypeHandler("META-INF/plugins.json") {
-
-  def readDependencies(in: JsonReader) = {
-    val deps = new ArrayBuffer[Dependency]
-    in.beginArray()
-    while (in.hasNext) {
-      in.beginObject()
-      var dep = Dependency(null, None)
-      while (in.hasNext) {
-        in.nextName() match {
-          case "id"      => dep = dep.copy(pluginId = in.nextString())
-          case "version" => dep = dep.copy(version = Option(in.nextString()))
-          case _         => in.skipValue()
-        }
-      }
-      deps += dep
-      in.endObject()
-    }
-    in.endArray()
-    deps.toSeq
-  }
-
-  def readAuthors(in: JsonReader) = {
-    val authors = new ArrayBuffer[String]
-    in.beginArray()
-    while (in.hasNext) {
-      in.beginObject()
-      while (in.hasNext) {
-        in.nextName() match {
-          case "name" => authors += in.nextString()
-          case _      => in.skipValue()
-        }
-      }
-      in.endObject()
-    }
-    in.endArray()
-    authors.toSeq
-  }
-
-  def readDataValue(dvs: ArrayBuffer[DataValue], in: JsonReader) = {
-    while (in.hasNext) {
-      in.nextName() match {
-        case "id"           => dvs += StringDataValue("id", in.nextString());
-        case "version"      => dvs += StringDataValue("version", in.nextString());
-        case "name"         => dvs += StringDataValue("name", in.nextString());
-        case "description"  => dvs += StringDataValue("description", in.nextString());
-        case "contributors" => dvs += StringListValue("authors", readAuthors(in));
-        case "dependencies" => dvs += DependencyDataValue("dependencies", readDependencies(in));
-        // case "links" =>
-        // case "main-class" =>
-        // case "loader" =>
-        case _ => in.skipValue() // ignored
-      }
-
-    }
-  }
-
-  def readDataValues(dvs: ArrayBuffer[DataValue], in: JsonReader): Unit = {
-    var first = true;
-    in.beginArray()
-    while (in.hasNext) {
-      if (first) {
-        in.beginObject()
-        readDataValue(dvs, in)
-        first = false;
-        in.endObject()
-      } else {
-        in.skipValue() // cannot handle multiple plugins for now
-      }
-    }
-    in.endArray()
-  }
+object SpongeJsonHandler extends FileTypeHandler("META-INF/sponge_plugins.json") {
 
   override def getData(bufferedReader: BufferedReader): Seq[DataValue] = {
-    val dataValues = new ArrayBuffer[DataValue]
     try {
-      val reader = new JsonReader(bufferedReader)
-      reader.beginObject()
-      try {
-        if (reader.hasNext) {
-          if (reader.nextName().equals("plugins")) {
-            readDataValues(dataValues, reader)
-          }
-        }
-      } finally {
-        reader.endObject()
-      }
-      dataValues.toSeq
+      val metadata    = MetadataParser.read(bufferedReader)
+      val firstPlugin = metadata.metadata.asScala.head
+      Seq[DataValue](
+        StringDataValue("id", firstPlugin.id),
+        StringDataValue("version", firstPlugin.version.toString),
+        StringListValue("authors", firstPlugin.contributors.asScala.map(_.name).toSeq),
+        DependencyDataValue("dependencies", readDependencies(firstPlugin.dependencies.asScala))
+      ) ++ Seq(
+        firstPlugin.name.toScala.map(v => StringDataValue("name", v)),
+        firstPlugin.description.toScala.map(v => StringDataValue("description", v))
+      ).flatten
     } catch {
-      case NonFatal(e) =>
+      case NonFatal(e) => {
         e.printStackTrace()
         Nil
+      }
     }
   }
+
+  def readDependencies(in: Iterable[PluginDependency]): Seq[Dependency] =
+    in.map { dep =>
+      Dependency(
+        dep.id,
+        Option.when(dep.version.hasRestrictions || dep.version.getRecommendedVersion != null)(dep.version.toString)
+      )
+    }.toSeq
+
 }
diff --git a/project/Settings.scala b/project/Settings.scala
index 32cd91f2a..5d464b1f6 100644
--- a/project/Settings.scala
+++ b/project/Settings.scala
@@ -11,7 +11,7 @@ object Settings {
   val scalaVer = "2.13.6"
 
   val commonSettings = Seq(
-    version := "2.0.0-M2.4",
+    version := "2.0.0-M2.5",
     scalaVersion := scalaVer,
     scalacOptions ++= Seq(
       "-deprecation",
diff --git a/project/dependencies.scala b/project/dependencies.scala
index 4fbadf9f5..560e6da18 100644
--- a/project/dependencies.scala
+++ b/project/dependencies.scala
@@ -90,7 +90,11 @@ object Deps {
     "ext-wikilink"
   ).map(flexmarkDep)
 
-  val pluginMeta = "org.spongepowered" % "plugin-meta" % "0.4.1"
+  // Sponge API-8+
+  val pluginMeta = "org.spongepowered" % "plugin-meta" % "0.8.0"
+
+  // mcmod.info
+  val pluginMetaMcMod = "org.spongepowered.plugin-meta" % "mcmod-info" % "0.8.0"
 
   val javaxMail = "javax.mail"     % "mail"            % "1.4.7"
   val postgres  = "org.postgresql" % "postgresql"      % "42.2.16"