diff --git a/leaf-api/paper-patches/features/0004-Paper-Avoid-and-discourage-use-of-Maven-Central-as-a.patch b/leaf-api/paper-patches/features/0004-Paper-Avoid-and-discourage-use-of-Maven-Central-as-a.patch
index e964b246..a58071fc 100644
--- a/leaf-api/paper-patches/features/0004-Paper-Avoid-and-discourage-use-of-Maven-Central-as-a.patch
+++ b/leaf-api/paper-patches/features/0004-Paper-Avoid-and-discourage-use-of-Maven-Central-as-a.patch
@@ -8,13 +8,23 @@ Original project: https://github.com/PaperMC/Paper
https://github.com/PaperMC/Paper/commit/62b7f86dae659deb2fc450285452d7c1439f92dc
+Dreeam's Note:
+We use soft warning which in Paper is directly exception throw,
+Only print warning to avoid break plugins directly.
+
+Also see `Configurable LibraryLoader maven repos` patch,
+able to match googleapi mirror urls, to replace to repo url we custom defined.
+This able to switch back to maven central repo, to prevent
+situation that dependencies exist in maven central, but not in mirror.
+---
+
Default LibraryLoader to Google's Maven Central mirror, add MavenLibraryResolver.MAVEN_CENTRAL_DEFAULT_MIRROR, and warn on use of Maven Central with MavenLibraryResolver
https://www.sonatype.com/blog/maven-central-and-the-tragedy-of-the-commons
https://www.sonatype.com/blog/beyond-ips-addressing-organizational-overconsumption-in-maven-central
diff --git a/src/main/java/io/papermc/paper/plugin/loader/library/impl/MavenLibraryResolver.java b/src/main/java/io/papermc/paper/plugin/loader/library/impl/MavenLibraryResolver.java
-index 107705db2d82b7c191e5e625ec888e0bc3b03831..ebb52c2c8d5fe8ca25513aadae8168180a3d426e 100644
+index 107705db2d82b7c191e5e625ec888e0bc3b03831..f12c25f35f3d26dc69e05c7965385e66a3d3d545 100644
--- a/src/main/java/io/papermc/paper/plugin/loader/library/impl/MavenLibraryResolver.java
+++ b/src/main/java/io/papermc/paper/plugin/loader/library/impl/MavenLibraryResolver.java
@@ -41,7 +41,7 @@ import org.slf4j.LoggerFactory;
@@ -51,22 +61,23 @@ index 107705db2d82b7c191e5e625ec888e0bc3b03831..ebb52c2c8d5fe8ca25513aadae816818
private static final Logger LOGGER = LoggerFactory.getLogger("MavenLibraryResolver");
private final RepositorySystem repository;
-@@ -105,6 +123,14 @@ public class MavenLibraryResolver implements ClassPathLibrary {
+@@ -105,6 +123,15 @@ public class MavenLibraryResolver implements ClassPathLibrary {
* dependencies from
*/
public void addRepository(final RemoteRepository remoteRepository) {
+ // Paper start - Avoid and discourage use of Maven Central as a CDN
+ if (MAVEN_CENTRAL_URLS.stream().anyMatch(remoteRepository.getUrl()::startsWith)) {
-+ LOGGER.warn(
-+ "Use of Maven Central as a CDN is against the Maven Central Terms of Service. Use MavenLibraryResolver.MAVEN_CENTRAL_DEFAULT_MIRROR instead.",
-+ new RuntimeException("Plugin used Maven Central for library resolution")
-+ );
++ try {
++ throw new RuntimeException("Plugin used Maven Central for library resolution");
++ } catch (RuntimeException e) {
++ LOGGER.error("Use of Maven Central as a CDN is against the Maven Central Terms of Service. Use MavenLibraryResolver.MAVEN_CENTRAL_DEFAULT_MIRROR instead.", e);
++ }
+ }
+ // Paper end - Avoid and discourage use of Maven Central as a CDN
this.repositories.add(remoteRepository);
}
-@@ -130,4 +156,17 @@ public class MavenLibraryResolver implements ClassPathLibrary {
+@@ -130,4 +157,17 @@ public class MavenLibraryResolver implements ClassPathLibrary {
store.addLibrary(file.toPath());
}
}
diff --git a/leaf-api/paper-patches/features/0018-Configurable-LibraryLoader-maven-repos.patch b/leaf-api/paper-patches/features/0018-Configurable-LibraryLoader-maven-repos.patch
index 22e28c5e..125dfdfe 100644
--- a/leaf-api/paper-patches/features/0018-Configurable-LibraryLoader-maven-repos.patch
+++ b/leaf-api/paper-patches/features/0018-Configurable-LibraryLoader-maven-repos.patch
@@ -7,17 +7,17 @@ Add JVM flag `-DLeaf.library-download-repo=link` to choose library download repo
e.g. `-DLeaf.library-download-repo=https://maven.aliyun.com/repository/public`
diff --git a/src/main/java/io/papermc/paper/plugin/loader/library/impl/MavenLibraryResolver.java b/src/main/java/io/papermc/paper/plugin/loader/library/impl/MavenLibraryResolver.java
-index ebb52c2c8d5fe8ca25513aadae8168180a3d426e..006a86da6afa1b7b80df5df073ebd236e27cd2b5 100644
+index f12c25f35f3d26dc69e05c7965385e66a3d3d545..f5fb8c3214a421c4d4f681176335dc92cf59834a 100644
--- a/src/main/java/io/papermc/paper/plugin/loader/library/impl/MavenLibraryResolver.java
+++ b/src/main/java/io/papermc/paper/plugin/loader/library/impl/MavenLibraryResolver.java
-@@ -60,12 +60,16 @@ public class MavenLibraryResolver implements ClassPathLibrary {
+@@ -60,12 +60,25 @@ public class MavenLibraryResolver implements ClassPathLibrary {
*
This repository is also used by the legacy {@link org.bukkit.plugin.java.LibraryLoader}.
*/
public static final String MAVEN_CENTRAL_DEFAULT_MIRROR = getDefaultMavenCentralMirror();
- private static final List MAVEN_CENTRAL_URLS = List.of(
+ // Leaf start - Configurable LibraryLoader maven repos
+ @org.jspecify.annotations.Nullable
-+ public static final RemoteRepository MAVEN_CENTRAL_MIRROR_REPO = getCentralMirrorRepo();
++ public static final RemoteRepository CUSTOM_MAVEN_CENTRAL_MIRROR_REPO = getCustomCentralMirrorRepo();
+ private static final String[] MAVEN_CENTRAL_URLS = new String[]{
"https://repo1.maven.org/maven2",
"http://repo1.maven.org/maven2",
@@ -25,45 +25,65 @@ index ebb52c2c8d5fe8ca25513aadae8168180a3d426e..006a86da6afa1b7b80df5df073ebd236
"http://repo.maven.apache.org/maven2"
- );
+ };
++ // From https://storage-download.googleapis.com/maven-central/index.html
++ private static final String[] MAVEN_CENTRAL_GOOGLE_MIRROR_URLS = new String[]{
++ "https://maven-central.storage-download.googleapis.com/maven2",
++ "http://maven-central.storage-download.googleapis.com/maven2",
++ "https://maven-central-eu.storage-download.googleapis.com/maven2",
++ "http://maven-central-eu.storage-download.googleapis.com/maven2",
++ "https://maven-central-asia.storage-download.googleapis.com/maven2",
++ "http://maven-central-asia.storage-download.googleapis.com/maven2"
++ };
+ // Leaf end - Configurable LibraryLoader maven repos
// Paper end - Avoid and discourage use of Maven Central as a CDN
private static final Logger LOGGER = LoggerFactory.getLogger("MavenLibraryResolver");
-@@ -124,12 +128,21 @@ public class MavenLibraryResolver implements ClassPathLibrary {
+@@ -124,13 +137,32 @@ public class MavenLibraryResolver implements ClassPathLibrary {
*/
public void addRepository(final RemoteRepository remoteRepository) {
// Paper start - Avoid and discourage use of Maven Central as a CDN
- if (MAVEN_CENTRAL_URLS.stream().anyMatch(remoteRepository.getUrl()::startsWith)) {
-- LOGGER.warn(
-- "Use of Maven Central as a CDN is against the Maven Central Terms of Service. Use MavenLibraryResolver.MAVEN_CENTRAL_DEFAULT_MIRROR instead.",
-- new RuntimeException("Plugin used Maven Central for library resolution")
-- );
+- try {
+- throw new RuntimeException("Plugin used Maven Central for library resolution");
+- } catch (RuntimeException e) {
+- LOGGER.error("Use of Maven Central as a CDN is against the Maven Central Terms of Service. Use MavenLibraryResolver.MAVEN_CENTRAL_DEFAULT_MIRROR instead.", e);
+ // Leaf start - Configurable LibraryLoader maven repos
-+ for (String url : MAVEN_CENTRAL_URLS) {
-+ if (remoteRepository.getUrl().startsWith(url)) {
-+ RemoteRepository mirrorRepo = MAVEN_CENTRAL_MIRROR_REPO;
-+ if (mirrorRepo != null) {
-+ this.repositories.add(mirrorRepo);
-+ return;
-+ }
-+ LOGGER.warn(
-+ "Use of Maven Central as a CDN is against the Maven Central Terms of Service. Use MavenLibraryResolver.MAVEN_CENTRAL_DEFAULT_MIRROR instead.",
-+ new RuntimeException("Plugin used Maven Central for library resolution")
-+ );
-+ }
++ for (String url : MAVEN_CENTRAL_URLS) {
++ if (remoteRepository.getUrl().startsWith(url)) {
++ RemoteRepository mirrorRepo = CUSTOM_MAVEN_CENTRAL_MIRROR_REPO;
++ if (mirrorRepo != null) {
++ this.repositories.add(mirrorRepo);
++ return;
++ }
++ try {
++ throw new RuntimeException("Plugin used Maven Central for library resolution");
++ } catch (RuntimeException e) {
++ LOGGER.error("Use of Maven Central as a CDN is against the Maven Central Terms of Service. Use MavenLibraryResolver.MAVEN_CENTRAL_DEFAULT_MIRROR instead.", e);
++ }
+ }
}
++ // Match google api maven central mirror urls
++ for (String url : MAVEN_CENTRAL_GOOGLE_MIRROR_URLS) {
++ if (remoteRepository.getUrl().startsWith(url)) {
++ RemoteRepository mirrorRepo = CUSTOM_MAVEN_CENTRAL_MIRROR_REPO;
++ if (mirrorRepo != null) {
++ this.repositories.add(mirrorRepo);
++ return;
++ }
++ }
++ }
+ // Leaf end - Configurable LibraryLoader maven repos
// Paper end - Avoid and discourage use of Maven Central as a CDN
this.repositories.add(remoteRepository);
}
-@@ -169,4 +182,15 @@ public class MavenLibraryResolver implements ClassPathLibrary {
+@@ -170,4 +202,15 @@ public class MavenLibraryResolver implements ClassPathLibrary {
return central;
}
// Paper end - Avoid and discourage use of Maven Central as a CDN
+
+ // Leaf start - Configurable LibraryLoader maven repos
+ @org.jspecify.annotations.Nullable
-+ private static RemoteRepository getCentralMirrorRepo() {
++ private static RemoteRepository getCustomCentralMirrorRepo() {
+ String mirrorAddr = System.getProperty("Leaf.library-download-repo");
+ if (mirrorAddr != null) {
+ return new RemoteRepository.Builder("central", "default", mirrorAddr).build();
@@ -73,14 +93,14 @@ index ebb52c2c8d5fe8ca25513aadae8168180a3d426e..006a86da6afa1b7b80df5df073ebd236
+ // Leaf end - Configurable LibraryLoader maven repos
}
diff --git a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
-index 1f2e86e9a830b990bbba3704889671465816ea1c..a16da10e38889af3a5878a6273d2982c707e93d2 100644
+index 1f2e86e9a830b990bbba3704889671465816ea1c..fce316374a0ae06a34acbce0907dfde52b7905e8 100644
--- a/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/LibraryLoader.java
@@ -49,6 +49,7 @@ public class LibraryLoader {
// Paper start - Avoid and discourage use of Maven Central as a CDN
private static List getRepositories() {
-+ if (io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver.MAVEN_CENTRAL_MIRROR_REPO != null) return List.of(io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver.MAVEN_CENTRAL_MIRROR_REPO); // Leaf - Configurable LibraryLoader maven repos
++ if (io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver.CUSTOM_MAVEN_CENTRAL_MIRROR_REPO != null) return List.of(io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver.CUSTOM_MAVEN_CENTRAL_MIRROR_REPO); // Leaf - Configurable LibraryLoader maven repos
return List.of(new RemoteRepository.Builder("central", "default", io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver.MAVEN_CENTRAL_DEFAULT_MIRROR).build());
}
// Paper end - Avoid and discourage use of Maven Central as a CDN