高速构建ForgeGradle

很多人都被ForgeGradle卡的不能自理,一方面是因为网速问题,另一方面是因为Gradle的一些设计理念问题.因此这里我大致讲一下我跟Gradle斗智斗勇一年半来积累的经♂验.

Gradle在下载依赖包时的策略是从第一个仓库(Repository)开始依次查找,如果能获取到符合maven格式的pom文件的话,便下载pom文件然后根据其内容下载其他文件,如果没有的话则会尝试根据"maven坐标"寻找并下载一个默认名字的文件,依然找不到的话则会到下一个源中继续此过程.因此在为Maven仓库排序时首先尽量把命中率高,或者说包含的依赖包最多的仓库排在前头;其次要考虑仓库在找不到依赖包时的失败速度,如果一个仓库没有目标依赖包的话,应当尽管返回失败信息让客户端继续寻找下一个仓库,然而由于各种各样的原因有些仓库会拖很久才会返回失败信息,甚至是干脆将客户端的连接挂起...因此仓库的快速失败性也是需要考虑的.

首先先拿buildscript的repositories来举例,ForgeGradle自带的那个构建文件中是这样的:

jcenter()
maven {
	name = "forge"
	url = "http://files.minecraftforge.net/maven"
}

这里可以替换为FMM:

maven {
	name = "forge"
	url = "http://forgemavenmirror.sinaapp.com/maven"
}

此时,你的buildscript的repositories应该是这样:

buildscript {
    repositories {
        maven {
            name = "forge"
            url = "http://forgemavenmirror.sinaapp.com/maven"
        }
    }
    dependencies {
        classpath 'net.minecraftforge.gradle:ForgeGradle:2.X-SNAPSHOT'
    }
}

然后我们需要调教其他的ForgeGradle下载源,如果你没有FGOW(ForgeGradle on Wall)而又不想改Hosts的话,那就只能止步于此了,因为其余的下载地址都是被硬编码进ForgeGradle插件的...不过幸运的是我们有FGOW.而且新版FMM已经可以缓存多个仓库的文件了,因此我建议使用FMM加速即可,以下的旧文是针对FMM尚不具备多仓库缓存能力时的方案,仅供参考.

旧文备档


FGOW的使用直接参考上面的那个链接即可,具体配置过程不再赘述,这里主要讲的构建脚本的repositories的设计.
ForgeGradle默认的顺序是这样:

Forge仓库:http://files.minecraftforge.net/maven
Maven主仓库
Minecraft仓库:https://libraries.minecraft.net/
本地缓存仓库:(Win7/8下是C:\Users\[用户名]\.gradle\caches\minecraft\net\minecraftforge\forge\[MC版本]-[Forge版本]\)

这里我们为它重新排布一下,首先我将本地缓存放到了最前面,虽然它包含的依赖包是最少的,但它的失败速度是最快的,因此即使有海量的未命中,所带来的时间损失仍能被那几次命中所弥补,在使用FGOW时,本地缓存仓库的写法是:

flatDir { name = "local" }

然后我将OSChina的Maven主仓库镜像排在了第二位,FMM的Forge仓库镜像排在了第三位.

maven {
name = "maven"
url = "http://maven.oschina.net/content/groups/public/"
}
maven {
name = "forge"
url = "http://forgemavenmirror.sinaapp.com/maven"
}
</code>
最后我将BMCLAPI2的Minecraft仓库排在了最后一位,这是因为BMCLAPI2会挂起无结果的请求的特性...
<code>maven {
name = "minecraft"
url = "http://bmclapi2.bangbang93.com/libraries"
}

此时,repositories应该是这样:

repositories {
flatDir { name = "local" }
maven {
name = "maven"
url = "http://maven.oschina.net/content/groups/public/"
}
maven {
name = "forge"
url = "http://forgemavenmirror.sinaapp.com/maven"
}
maven {
name = "minecraft"
url = "http://bmclapi2.bangbang93.com/libraries"
}
}

整个构建脚本的前半部分应该类似这样:

buildscript {
repositories {
maven {
name = "maven"
url = "http://maven.oschina.net/content/groups/public/"
}
maven {
name = "forge"
url = "http://forgemavenmirror.sinaapp.com/maven"
}
maven {
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT'
classpath files('fgow-1.1.0.jar')
}
}

ext.mcpJsonUrl = "http://forgemavenmirror.sinaapp.com/versions.json"
ext.forgeJsonUrl = "http://forgemavenmirror.sinaapp.com/maven/net/minecraftforge/forge/json"

apply plugin: 'fgow'

repos {
mcJsonUrl = "http://bmclapi2.bangbang93.com/versions/{MC_VERSION}/{MC_VERSION}.json"
mcClientUrl = "http://bmclapi2.bangbang93.com/versions/{MC_VERSION}/{MC_VERSION}.jar"
mcServerUrl = "http://bmclapi2.bangbang93.com/versions/{MC_VERSION}/minecraft_server.{MC_VERSION}.jar"
assestIndexUrl = "http://bmclapi2.bangbang93.com/indexes/{ASSET_INDEX}.json"
assestUrl = "http://bmclapi2.bangbang93.com/assets"
mcpUrl = "http://forgemavenmirror.sinaapp.com/fernflower-fix-1.0.zip"
}

repositories {
flatDir { name = "local" }
maven {
name = "maven"
url = "http://maven.oschina.net/content/groups/public/"
}
maven {
name = "forge"
url = "http://forgemavenmirror.sinaapp.com/maven"
}
maven {
name = "minecraft"
url = "http://bmclapi2.bangbang93.com/libraries"
}
}

//构建脚本的后半部分,比如archivesBaseName什么的...