-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: download and extract default resourcePack for use in other plugins
- Loading branch information
Showing
3 changed files
with
117 additions
and
2 deletions.
There are no files selected for viewing
8 changes: 8 additions & 0 deletions
8
idofront-catalog-shaded/src/main/java/com/mineinabyss/idofront/IdofrontPlugin.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,14 @@ | ||
package com.mineinabyss.idofront | ||
|
||
import com.mineinabyss.idofront.resourcepacks.MinecraftAssetExtractor | ||
import org.bukkit.Bukkit | ||
import org.bukkit.plugin.java.JavaPlugin | ||
|
||
class IdofrontPlugin : JavaPlugin() { | ||
|
||
override fun onEnable() { | ||
Bukkit.getAsyncScheduler().runNow(this) { | ||
MinecraftAssetExtractor.extractLatest() | ||
} | ||
} | ||
} |
96 changes: 96 additions & 0 deletions
96
...nt-util/src/main/kotlin/com/mineinabyss/idofront/resourcepacks/MinecraftAssetExtractor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package com.mineinabyss.idofront.resourcepacks | ||
|
||
import com.google.gson.JsonObject | ||
import com.google.gson.JsonParser | ||
import com.mineinabyss.idofront.messaging.idofrontLogger | ||
import org.bukkit.Bukkit | ||
import java.io.ByteArrayInputStream | ||
import java.io.File | ||
import java.io.FileOutputStream | ||
import java.net.URI | ||
import java.util.zip.ZipEntry | ||
import java.util.zip.ZipInputStream | ||
|
||
|
||
object MinecraftAssetExtractor { | ||
|
||
private const val VERSION_MANIFEST_URL = "https://piston-meta.mojang.com/mc/game/version_manifest_v2.json" | ||
lateinit var assetPath: File | ||
|
||
fun extractLatest() { | ||
idofrontLogger.i("Extracting latest vanilla-assets...") | ||
val versionInfo = runCatching { | ||
downloadJson(findVersionInfoUrl() ?: return)?.asJsonObject | ||
}.getOrNull() ?: return | ||
|
||
val clientJar = downloadClientJar(versionInfo) | ||
extractJarAssets(clientJar, assetPath) | ||
idofrontLogger.s("Finished extracting vanilla assets for ${assetPath.name}") | ||
} | ||
|
||
private fun extractJarAssets(clientJar: ByteArray?, assetPath: File) { | ||
var entry: ZipEntry | ||
|
||
ByteArrayInputStream(clientJar).use { inputStream -> | ||
ZipInputStream(inputStream).use { zipInputStream -> | ||
|
||
kotlin.runCatching { | ||
while (zipInputStream.nextEntry.also { entry = it } != null) { | ||
if (!entry.name.startsWith("assets/")) continue | ||
if (entry.name.startsWith("assets/minecraft/shaders")) continue | ||
if (entry.name.startsWith("assets/minecraft/particles")) continue | ||
|
||
val file = checkAndCreateFile(assetPath, entry) | ||
if (entry.isDirectory && !file.isDirectory && !file.mkdirs()) | ||
error("Failed to create directory ${entry.name}") | ||
else { | ||
val parent = file.parentFile | ||
if (!parent.isDirectory && !parent.mkdirs()) error("Failed to create directory ${parent?.path}") | ||
|
||
runCatching { | ||
zipInputStream.copyTo(FileOutputStream(file)) | ||
}.onFailure { | ||
error("Failed to extract ${entry.name} from ${parent?.path}") | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private fun checkAndCreateFile(assetPath: File, entry: ZipEntry): File { | ||
val destFile = assetPath.resolve(entry.name) | ||
val dirPath = assetPath.canonicalPath | ||
val filePath = destFile.canonicalPath | ||
|
||
if (!filePath.startsWith(dirPath + File.separator)) error("Entry outside target: ${entry.name}") | ||
return destFile | ||
} | ||
|
||
private fun downloadClientJar(versionInfo: JsonObject) = runCatching { | ||
val url = versionInfo.getAsJsonObject("downloads").getAsJsonObject("client").get("url").asString | ||
URI(url).toURL().readBytes() | ||
}.onFailure { it.printStackTrace() }.getOrNull() ?: error("Failed to download client JAR") | ||
|
||
private fun findVersionInfoUrl(): String? { | ||
val manifest = runCatching { | ||
downloadJson(VERSION_MANIFEST_URL) | ||
}.getOrNull() ?: error("Failed to download version manifest") | ||
|
||
val latest = manifest.getAsJsonObject("latest").get("release").asString | ||
assetPath = Bukkit.getPluginsFolder().resolve("Idofront/assetCache/$latest") | ||
|
||
if (!assetPath.mkdirs()) { | ||
idofrontLogger.i("Latest has already been extracted for $latest, skipping...") | ||
return null | ||
} | ||
|
||
return manifest.getAsJsonArray("versions").firstOrNull { | ||
(it as? JsonObject)?.get("id")?.asString?.equals(latest) ?: false | ||
}?.asJsonObject?.get("url")?.asString ?: error("Failed to find version inof url for version $latest") | ||
} | ||
|
||
private fun downloadJson(url: String) = runCatching { JsonParser.parseString(URI.create(url).toURL().readText()) } | ||
.getOrNull()?.takeIf { it.isJsonObject }?.asJsonObject | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters