mirror of
https://github.com/HMCL-dev/HMCL.git
synced 2025-09-17 15:57:18 -04:00
HMCL modpack output model
This commit is contained in:
parent
d83291eac0
commit
86cef86fc9
@ -22,12 +22,21 @@ import org.jackhuang.hmcl.download.game.VersionJSONSaveTask
|
|||||||
import org.jackhuang.hmcl.mod.Modpack
|
import org.jackhuang.hmcl.mod.Modpack
|
||||||
import org.jackhuang.hmcl.setting.Profile
|
import org.jackhuang.hmcl.setting.Profile
|
||||||
import org.jackhuang.hmcl.task.Task
|
import org.jackhuang.hmcl.task.Task
|
||||||
import org.jackhuang.hmcl.util.GSON
|
|
||||||
import org.jackhuang.hmcl.util.fromJson
|
|
||||||
import org.jackhuang.hmcl.util.readTextFromZipFile
|
|
||||||
import org.jackhuang.hmcl.util.unzipSubDirectory
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
import sun.misc.IOUtils
|
||||||
|
import jdk.nashorn.internal.objects.NativeFunction.call
|
||||||
|
import org.jackhuang.hmcl.task.TaskResult
|
||||||
|
import org.jackhuang.hmcl.util.*
|
||||||
|
import sun.plugin2.util.PojoUtil.toJson
|
||||||
|
import sun.tools.jar.resources.jar
|
||||||
|
import java.util.Collections.addAll
|
||||||
|
import java.util.ArrayList
|
||||||
|
import java.util.Arrays
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the manifest in a HMCL modpack.
|
* Read the manifest in a HMCL modpack.
|
||||||
@ -71,3 +80,42 @@ class HMCLModpackInstallTask(profile: Profile, private val zipFile: File, privat
|
|||||||
json.delete()
|
json.delete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val MODPACK_BLACK_LIST = listOf("usernamecache.json", "asm", "logs", "backups", "versions", "assets", "usercache.json", "libraries", "crash-reports", "launcher_profiles.json", "NVIDIA", "AMD", "TCNodeTracker", "screenshots", "natives", "native", "\$native", "pack.json", "launcher.jar", "minetweaker.log", "launcher.pack.lzma", "hmclmc.log")
|
||||||
|
val MODPACK_SUGGESTED_BLACK_LIST = listOf("fonts", "saves", "servers.dat", "options.txt", "optionsof.txt", "journeymap", "optionsshaders.txt", "mods/VoxelMods")
|
||||||
|
|
||||||
|
class HMCLModpackExportTask @JvmOverloads constructor(
|
||||||
|
private val repository: DefaultGameRepository,
|
||||||
|
private val version: String,
|
||||||
|
private val blacklist: List<String>,
|
||||||
|
private val modpack: Modpack,
|
||||||
|
private val output: File,
|
||||||
|
override val id: String = ID): TaskResult<ZipEngine>() {
|
||||||
|
override fun execute() {
|
||||||
|
val b = ArrayList<String>(MODPACK_BLACK_LIST)
|
||||||
|
b.addAll(blacklist)
|
||||||
|
b.add(version + ".jar")
|
||||||
|
b.add(version + ".json")
|
||||||
|
LOG.info("Compressing game files without some files in blacklist, including files or directories: usernamecache.json, asm, logs, backups, versions, assets, usercache.json, libraries, crash-reports, launcher_profiles.json, NVIDIA, TCNodeTracker")
|
||||||
|
ZipEngine(output).use { zip ->
|
||||||
|
zip.putDirectory(repository.getRunDirectory(version)) a@ { x: String, y: Boolean ->
|
||||||
|
for (s in b)
|
||||||
|
if (y) {
|
||||||
|
if (x.startsWith(s + "/"))
|
||||||
|
return@a null
|
||||||
|
} else if (x == s)
|
||||||
|
return@a null
|
||||||
|
"minecraft/" + x
|
||||||
|
}
|
||||||
|
|
||||||
|
val mv = repository.getVersion(version).resolve(repository)
|
||||||
|
val gameVersion = minecraftVersion(repository.getVersionJar(version)) ?: throw IllegalStateException("Cannot parse the version of $version")
|
||||||
|
zip.putTextFile(GSON.toJson(mv), "minecraft/pack.json")
|
||||||
|
zip.putTextFile(GSON.toJson(modpack.copy(gameVersion = gameVersion)), "modpack.json")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val ID = "zip_engine"
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ data class Modpack @JvmOverloads constructor(
|
|||||||
val name: String = "",
|
val name: String = "",
|
||||||
val author: String = "",
|
val author: String = "",
|
||||||
val version: String = "",
|
val version: String = "",
|
||||||
|
val gameVersion: String = "",
|
||||||
val description: String = "",
|
val description: String = "",
|
||||||
val manifest: Any? = null
|
val manifest: Any? = null
|
||||||
)
|
)
|
126
HMCLCore/src/main/kotlin/org/jackhuang/hmcl/util/ZipEngine.kt
Normal file
126
HMCLCore/src/main/kotlin/org/jackhuang/hmcl/util/ZipEngine.kt
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hmcl.util
|
||||||
|
|
||||||
|
import java.util.zip.ZipEntry
|
||||||
|
import java.util.HashSet
|
||||||
|
import java.io.*
|
||||||
|
import java.util.zip.ZipOutputStream
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Non thread-safe
|
||||||
|
*
|
||||||
|
* @author huangyuhui
|
||||||
|
*/
|
||||||
|
class ZipEngine
|
||||||
|
@Throws(IOException::class)
|
||||||
|
constructor(f: File) : Closeable {
|
||||||
|
|
||||||
|
val buf = ByteArray(1024)
|
||||||
|
val zos: ZipOutputStream = ZipOutputStream(BufferedOutputStream(f.outputStream()))
|
||||||
|
private val names = HashSet<String>()
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun close() {
|
||||||
|
zos.closeEntry()
|
||||||
|
zos.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 功能:把 sourceDir 目录下的所有文件进行 zip 格式的压缩,保存为指定 zip 文件
|
||||||
|
*
|
||||||
|
* @param sourceDir 源文件夹
|
||||||
|
* @param pathNameCallback callback(pathName, isDirectory) returns your
|
||||||
|
* modified pathName
|
||||||
|
*
|
||||||
|
* @throws java.io.IOException 压缩失败或无法读取
|
||||||
|
*/
|
||||||
|
@Throws(IOException::class)
|
||||||
|
@JvmOverloads
|
||||||
|
fun putDirectory(sourceDir: File, pathNameCallback: ((String, Boolean) -> String?)? = null) {
|
||||||
|
putDirectoryImpl(sourceDir, if (sourceDir.isDirectory) sourceDir.path else sourceDir.parent, pathNameCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将文件压缩成zip文件
|
||||||
|
*
|
||||||
|
* @param source zip文件路径
|
||||||
|
* @param basePath 待压缩文件根目录
|
||||||
|
* @param zos zip文件的os
|
||||||
|
* @param pathNameCallback callback(pathName, isDirectory) returns your
|
||||||
|
* modified pathName, null if you dont want this file zipped
|
||||||
|
*/
|
||||||
|
@Throws(IOException::class)
|
||||||
|
private fun putDirectoryImpl(source: File, basePath: String, pathNameCallback: ((String, Boolean) -> String?)?) {
|
||||||
|
val files: Array<File>?
|
||||||
|
if (source.isDirectory)
|
||||||
|
files = source.listFiles()
|
||||||
|
else
|
||||||
|
files = arrayOf(source)
|
||||||
|
if (files == null)
|
||||||
|
return
|
||||||
|
var pathName: String? //存相对路径(相对于待压缩的根目录)
|
||||||
|
for (file in files)
|
||||||
|
if (file.isDirectory) {
|
||||||
|
pathName = file.path.substring(basePath.length + 1) + "/"
|
||||||
|
pathName = pathName.replace('\\', '/')
|
||||||
|
if (pathNameCallback != null)
|
||||||
|
pathName = pathNameCallback(pathName, true)
|
||||||
|
if (pathName == null)
|
||||||
|
continue
|
||||||
|
put(ZipEntry(pathName))
|
||||||
|
putDirectoryImpl(file, basePath, pathNameCallback)
|
||||||
|
} else {
|
||||||
|
if (".DS_Store" == file.name) // For Mac computers.
|
||||||
|
continue
|
||||||
|
pathName = file.path.substring(basePath.length + 1)
|
||||||
|
pathName = pathName.replace('\\', '/')
|
||||||
|
if (pathNameCallback != null)
|
||||||
|
pathName = pathNameCallback(pathName, false)
|
||||||
|
if (pathName == null)
|
||||||
|
continue
|
||||||
|
putFile(file, pathName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun putFile(file: File, pathName: String) =
|
||||||
|
file.inputStream().use { putStream(it, pathName) }
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun putStream(inputStream: InputStream, pathName: String) {
|
||||||
|
put(ZipEntry(pathName))
|
||||||
|
inputStream.copyTo(zos, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun putTextFile(text: String, pathName: String) =
|
||||||
|
putTextFile(text, "UTF-8", pathName)
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun putTextFile(text: String, encoding: String, pathName: String) =
|
||||||
|
putStream(ByteArrayInputStream(text.toByteArray(charset(encoding))), pathName)
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun put(entry: ZipEntry) {
|
||||||
|
if (names.add(entry.name))
|
||||||
|
zos.putNextEntry(entry)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user