高速構建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什麼的...